summaryrefslogtreecommitdiffstats
path: root/nsprpub/pr/src/io
diff options
context:
space:
mode:
Diffstat (limited to 'nsprpub/pr/src/io')
-rw-r--r--nsprpub/pr/src/io/prio.c4
-rw-r--r--nsprpub/pr/src/io/prlayer.c59
-rw-r--r--nsprpub/pr/src/io/prmmap.c9
-rw-r--r--nsprpub/pr/src/io/prscanf.c8
-rw-r--r--nsprpub/pr/src/io/prsocket.c115
5 files changed, 155 insertions, 40 deletions
diff --git a/nsprpub/pr/src/io/prio.c b/nsprpub/pr/src/io/prio.c
index 78cbdf564..bf9763a2c 100644
--- a/nsprpub/pr/src/io/prio.c
+++ b/nsprpub/pr/src/io/prio.c
@@ -119,6 +119,10 @@ PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(
fd->methods = methods;
fd->secret->state = _PR_FILEDESC_OPEN;
fd->secret->md.osfd = osfd;
+#if defined(_WIN64)
+ fd->secret->alreadyConnected = PR_FALSE;
+ fd->secret->overlappedActive = PR_FALSE;
+#endif
_PR_MD_INIT_FILEDESC(fd);
} else {
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
diff --git a/nsprpub/pr/src/io/prlayer.c b/nsprpub/pr/src/io/prlayer.c
index cadb7ca3c..00da0287a 100644
--- a/nsprpub/pr/src/io/prlayer.c
+++ b/nsprpub/pr/src/io/prlayer.c
@@ -47,7 +47,8 @@ static PRStatus PR_CALLBACK pl_TopClose (PRFileDesc *fd)
rv = fd->lower->methods->close(fd->lower);
_PR_DestroyIOLayer(fd);
return rv;
- } else if ((fd->higher) && (PR_IO_LAYER_HEAD == fd->higher->identity)) {
+ }
+ if ((fd->higher) && (PR_IO_LAYER_HEAD == fd->higher->identity)) {
/*
* lower layers of new style stack
*/
@@ -201,16 +202,16 @@ static PRFileDesc* PR_CALLBACK pl_TopAccept (
return NULL;
}
- if (newstyle_stack) {
- newstack->lower = newfd;
- newfd->higher = newstack;
- return newstack;
- } else {
- /* this PR_PushIOLayer call cannot fail */
- rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);
- PR_ASSERT(PR_SUCCESS == rv);
- return newfd; /* that's it */
- }
+ if (newstyle_stack)
+ {
+ newstack->lower = newfd;
+ newfd->higher = newstack;
+ return newstack;
+ }
+ /* this PR_PushIOLayer call cannot fail */
+ rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);
+ PR_ASSERT(PR_SUCCESS == rv);
+ return newfd; /* that's it */
}
static PRStatus PR_CALLBACK pl_DefBind (PRFileDesc *fd, const PRNetAddr *addr)
@@ -326,12 +327,11 @@ static PRInt32 PR_CALLBACK pl_DefAcceptread (
(*nd)->higher = newstack;
*nd = newstack;
return nbytes;
- } else {
- /* this PR_PushIOLayer call cannot fail */
- rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack);
- PR_ASSERT(PR_SUCCESS == rv);
- return nbytes;
}
+ /* this PR_PushIOLayer call cannot fail */
+ rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack);
+ PR_ASSERT(PR_SUCCESS == rv);
+ return nbytes;
}
static PRInt32 PR_CALLBACK pl_DefTransmitfile (
@@ -494,10 +494,9 @@ static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack)
{
if (NULL == stack)
return PR_FAILURE;
- else {
- PR_DELETE(stack);
- return PR_SUCCESS;
- }
+
+ PR_DELETE(stack);
+ return PR_SUCCESS;
} /* _PR_DestroyIOLayer */
PR_IMPLEMENT(PRStatus) PR_PushIOLayer(
@@ -652,9 +651,11 @@ retry:
if ((NULL != names) && (identity < length))
{
/* what we did is still okay */
- memcpy(
- names, identity_cache.name,
- identity_cache.length * sizeof(char*));
+ if (identity_cache.length != 0) {
+ memcpy(
+ names, identity_cache.name,
+ identity_cache.length * sizeof(char*));
+ }
old = identity_cache.name;
identity_cache.name = names;
identity_cache.length = length;
@@ -702,8 +703,8 @@ PR_IMPLEMENT(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd)
if (PR_IO_LAYER_HEAD == fd->identity) {
PR_ASSERT(NULL != fd->lower);
return fd->lower->identity;
- } else
- return fd->identity;
+ }
+ return fd->identity;
} /* PR_GetLayersIdentity */
PR_IMPLEMENT(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd, PRDescIdentity id)
@@ -711,10 +712,10 @@ PR_IMPLEMENT(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd, PRDescIdentity i
PRFileDesc *layer = fd;
if (PR_TOP_IO_LAYER == id) {
- if (PR_IO_LAYER_HEAD == fd->identity)
- return fd->lower;
- else
- return fd;
+ if (PR_IO_LAYER_HEAD == fd->identity) {
+ return fd->lower;
+ }
+ return fd;
}
for (layer = fd; layer != NULL; layer = layer->lower)
diff --git a/nsprpub/pr/src/io/prmmap.c b/nsprpub/pr/src/io/prmmap.c
index 6ffc13305..64f7ed4e8 100644
--- a/nsprpub/pr/src/io/prmmap.c
+++ b/nsprpub/pr/src/io/prmmap.c
@@ -24,17 +24,16 @@ PR_IMPLEMENT(PRFileMap *) PR_CreateFileMap(
|| prot == PR_PROT_WRITECOPY);
fmap = PR_NEWZAP(PRFileMap);
if (NULL == fmap) {
- PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
- return NULL;
+ PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ return NULL;
}
fmap->fd = fd;
fmap->prot = prot;
if (_PR_MD_CREATE_FILE_MAP(fmap, size) == PR_SUCCESS) {
- return fmap;
- } else {
+ return fmap;
+ }
PR_DELETE(fmap);
return NULL;
- }
}
PR_IMPLEMENT(PRInt32) PR_GetMemMapAlignment(void)
diff --git a/nsprpub/pr/src/io/prscanf.c b/nsprpub/pr/src/io/prscanf.c
index 9d75d824e..377a6e643 100644
--- a/nsprpub/pr/src/io/prscanf.c
+++ b/nsprpub/pr/src/io/prscanf.c
@@ -409,7 +409,8 @@ Convert(ScanfState *state, const char *fmt)
ch = GET(state);
if (ch == EOF) {
return NULL;
- } else if (state->assign) {
+ }
+ if (state->assign) {
*cArg++ = ch;
}
}
@@ -602,10 +603,9 @@ StringGetChar(void *stream)
if (*cPtr == '\0') {
return EOF;
- } else {
- *((char **) stream) = cPtr + 1;
- return (unsigned char) *cPtr;
}
+ *((char **) stream) = cPtr + 1;
+ return (unsigned char) *cPtr;
}
static void
diff --git a/nsprpub/pr/src/io/prsocket.c b/nsprpub/pr/src/io/prsocket.c
index be9702408..a24b8e1bb 100644
--- a/nsprpub/pr/src/io/prsocket.c
+++ b/nsprpub/pr/src/io/prsocket.c
@@ -7,6 +7,12 @@
#include <string.h>
+#if defined(_WIN64)
+#ifndef SO_UPDATE_CONNECT_CONTEXT
+#define SO_UPDATE_CONNECT_CONTEXT 0x7010
+#endif
+#endif
+
/************************************************************************/
/* These two functions are only used in assertions. */
@@ -304,6 +310,48 @@ static PRStatus PR_CALLBACK SocketConnectContinue(
}
PR_ASSERT(out_flags & PR_POLL_WRITE);
+
+#if defined(_WIN64)
+ if (fd->secret->alreadyConnected) {
+ fd->secret->alreadyConnected = PR_FALSE;
+ }
+ /* TCP Fast Open on Windows must use ConnectEx, which uses overlapped
+ * input/output.
+ * To get result we need to use GetOverlappedResult. */
+ if (fd->secret->overlappedActive) {
+ PR_ASSERT(fd->secret->nonblocking);
+ PRInt32 rvSent;
+ if (GetOverlappedResult(osfd, &fd->secret->ol, &rvSent, FALSE) == TRUE) {
+ fd->secret->overlappedActive = PR_FALSE;
+ PR_LOG(_pr_io_lm, PR_LOG_MIN,
+ ("SocketConnectContinue GetOverlappedResult succeeded\n"));
+ /* When ConnectEx is used, all previously set socket options and
+ * property are not enabled and to enable them
+ * SO_UPDATE_CONNECT_CONTEXT option need to be set. */
+ if (setsockopt((SOCKET)osfd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0) != 0) {
+ err = WSAGetLastError();
+ PR_LOG(_pr_io_lm, PR_LOG_MIN,
+ ("SocketConnectContinue setting SO_UPDATE_CONNECT_CONTEXT failed %d\n", err));
+ _PR_MD_MAP_SETSOCKOPT_ERROR(err);
+ return PR_FAILURE;
+ }
+ return PR_SUCCESS;
+ } else {
+ err = WSAGetLastError();
+ PR_LOG(_pr_io_lm, PR_LOG_MIN,
+ ("SocketConnectContinue GetOverlappedResult failed %d\n", err));
+ if (err != ERROR_IO_INCOMPLETE) {
+ _PR_MD_MAP_CONNECT_ERROR(err);
+ fd->secret->overlappedActive = PR_FALSE;
+ return PR_FAILURE;
+ } else {
+ PR_SetError(PR_IN_PROGRESS_ERROR, 0);
+ return PR_FAILURE;
+ }
+ }
+ }
+#endif
+
return PR_SUCCESS;
#elif defined(XP_OS2)
@@ -751,7 +799,7 @@ static PRInt32 PR_CALLBACK SocketSendTo(
#endif
count = 0;
- while (amount > 0) {
+ do {
temp = _PR_MD_SENDTO(fd, buf, amount, flags,
addrp, PR_NETADDR_SIZE(addr), timeout);
if (temp < 0) {
@@ -764,10 +812,60 @@ static PRInt32 PR_CALLBACK SocketSendTo(
}
buf = (const void*) ((const char*)buf + temp);
amount -= temp;
- }
+ } while (amount > 0);
return count;
}
+#if defined(_WIN64) && defined(WIN95)
+static PRInt32 PR_CALLBACK SocketTCPSendTo(
+ PRFileDesc *fd, const void *buf, PRInt32 amount,
+ PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+ PRInt32 temp, count;
+ const PRNetAddr *addrp = addr;
+#if defined(_PR_INET6)
+ PRNetAddr addrCopy;
+#endif
+ PRThread *me = _PR_MD_CURRENT_THREAD();
+
+ if (_PR_PENDING_INTERRUPT(me)) {
+ me->flags &= ~_PR_INTERRUPT;
+ PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+ return -1;
+ }
+ if (_PR_IO_PENDING(me)) {
+ PR_SetError(PR_IO_PENDING_ERROR, 0);
+ return -1;
+ }
+
+ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+#if defined(_PR_INET6)
+ if (addr->raw.family == PR_AF_INET6) {
+ addrCopy = *addr;
+ addrCopy.raw.family = AF_INET6;
+ addrp = &addrCopy;
+ }
+#endif
+
+ count = 0;
+ while (amount > 0) {
+ temp = _PR_MD_TCPSENDTO(fd, buf, amount, flags,
+ addrp, PR_NETADDR_SIZE(addr), timeout);
+ if (temp < 0) {
+ count = -1;
+ break;
+ }
+ count += temp;
+ if (fd->secret->nonblocking) {
+ break;
+ }
+ buf = (const void*) ((const char*)buf + temp);
+ amount -= temp;
+ }
+ return count;
+}
+#endif
+
static PRInt32 PR_CALLBACK SocketRecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,
PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
{
@@ -1066,6 +1164,15 @@ static PRInt16 PR_CALLBACK SocketPoll(
PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
{
*out_flags = 0;
+
+#if defined(_WIN64)
+ if (in_flags & PR_POLL_WRITE) {
+ if (fd->secret->alreadyConnected) {
+ out_flags = PR_POLL_WRITE;
+ return PR_POLL_WRITE;
+ }
+ }
+#endif
return in_flags;
} /* SocketPoll */
@@ -1090,7 +1197,11 @@ static PRIOMethods tcpMethods = {
SocketRecv,
SocketSend,
(PRRecvfromFN)_PR_InvalidInt,
+#if defined(_WIN64) && defined(WIN95)
+ SocketTCPSendTo, /* This is for fast open. We imitate Linux interface. */
+#else
(PRSendtoFN)_PR_InvalidInt,
+#endif
SocketPoll,
SocketAcceptRead,
SocketTransmitFile,