summaryrefslogtreecommitdiffstats
path: root/nsprpub/pr/src
diff options
context:
space:
mode:
Diffstat (limited to 'nsprpub/pr/src')
-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
-rw-r--r--nsprpub/pr/src/md/unix/unix.c22
-rw-r--r--nsprpub/pr/src/md/unix/uxproces.c22
-rw-r--r--nsprpub/pr/src/md/unix/uxshm.c44
-rw-r--r--nsprpub/pr/src/md/windows/w32poll.c2
-rw-r--r--nsprpub/pr/src/md/windows/w95sock.c172
-rw-r--r--nsprpub/pr/src/misc/praton.c8
-rw-r--r--nsprpub/pr/src/misc/prnetdb.c49
-rw-r--r--nsprpub/pr/src/misc/prtime.c66
-rw-r--r--nsprpub/pr/src/misc/prtpool.c18
-rw-r--r--nsprpub/pr/src/prvrsion.c7
-rw-r--r--nsprpub/pr/src/pthreads/ptio.c234
-rw-r--r--nsprpub/pr/src/pthreads/ptsynch.c5
17 files changed, 629 insertions, 215 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,
diff --git a/nsprpub/pr/src/md/unix/unix.c b/nsprpub/pr/src/md/unix/unix.c
index fdae1199c..662f561b6 100644
--- a/nsprpub/pr/src/md/unix/unix.c
+++ b/nsprpub/pr/src/md/unix/unix.c
@@ -3316,11 +3316,11 @@ int _MD_unix_get_nonblocking_connect_error(int osfd)
return errno;
} else {
return err;
- }
+ }
}
} else {
return ECONNREFUSED;
- }
+ }
#elif defined(UNIXWARE)
/*
* getsockopt() fails with EPIPE, so use getmsg() instead.
@@ -3331,17 +3331,17 @@ int _MD_unix_get_nonblocking_connect_error(int osfd)
rv = getmsg(osfd, NULL, NULL, &flags);
PR_ASSERT(-1 == rv || 0 == rv);
if (-1 == rv && errno != EAGAIN && errno != EWOULDBLOCK) {
- return errno;
+ return errno;
}
- return 0; /* no error */
+ return 0; /* no error */
#else
- int err;
- _PRSockLen_t optlen = sizeof(err);
- if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen) == -1) {
- return errno;
- } else {
- return err;
- }
+ int err;
+ _PRSockLen_t optlen = sizeof(err);
+ if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char*)&err, &optlen) == -1) {
+ return errno;
+ }
+ return err;
+
#endif
}
diff --git a/nsprpub/pr/src/md/unix/uxproces.c b/nsprpub/pr/src/md/unix/uxproces.c
index a3b35e540..5286b9e18 100644
--- a/nsprpub/pr/src/md/unix/uxproces.c
+++ b/nsprpub/pr/src/md/unix/uxproces.c
@@ -247,13 +247,14 @@ ForkAndExec(
PR_DELETE(newEnvp);
}
return NULL;
- } else if (0 == process->md.pid) { /* the child process */
- /*
- * If the child process needs to exit, it must call _exit().
- * Do not call exit(), because exit() will flush and close
- * the standard I/O file descriptors, and hence corrupt
- * the parent process's standard I/O data structures.
- */
+ }
+ if (0 == process->md.pid) { /* the child process */
+ /*
+ * If the child process needs to exit, it must call _exit().
+ * Do not call exit(), because exit() will flush and close
+ * the standard I/O file descriptors, and hence corrupt
+ * the parent process's standard I/O data structures.
+ */
#if !defined(NTO) && !defined(SYMBIAN)
if (attr) {
@@ -498,10 +499,9 @@ ExtractExitStatus(int rawExitStatus)
#endif
if (WIFEXITED(rawExitStatus)) {
return WEXITSTATUS(rawExitStatus);
- } else {
+ }
PR_ASSERT(WIFSIGNALED(rawExitStatus));
return _PR_SIGNALED_EXITSTATUS;
- }
}
static void
@@ -624,8 +624,8 @@ static void WaitPidDaemonThread(void *unused)
} while (sizeof(buf) == rv || (-1 == rv && EINTR == errno));
#ifdef _PR_SHARE_CLONES
- PR_Unlock(pr_wp.ml);
while ((op = pr_wp.opHead) != NULL) {
+ PR_Unlock(pr_wp.ml);
op->process = ForkAndExec(op->path, op->argv,
op->envp, op->attr);
if (NULL == op->process) {
@@ -639,8 +639,8 @@ static void WaitPidDaemonThread(void *unused)
}
op->done = PR_TRUE;
PR_NotifyCondVar(op->doneCV);
- PR_Unlock(pr_wp.ml);
}
+ PR_Unlock(pr_wp.ml);
#endif
while (1) {
diff --git a/nsprpub/pr/src/md/unix/uxshm.c b/nsprpub/pr/src/md/unix/uxshm.c
index dec4e3a7a..54e68191c 100644
--- a/nsprpub/pr/src/md/unix/uxshm.c
+++ b/nsprpub/pr/src/md/unix/uxshm.c
@@ -76,8 +76,8 @@ extern PRSharedMemory * _MD_OpenSharedMemory(
/* copy args to struct */
strcpy( shm->ipcname, ipcname );
- shm->size = size;
- shm->mode = mode;
+ shm->size = size;
+ shm->mode = mode;
shm->flags = flags;
shm->ident = _PR_SHM_IDENT;
@@ -500,30 +500,32 @@ extern PRFileMap* _md_OpenAnonFileMap(
("_md_OpenAnonFileMap(): PR_snprintf(): failed, generating filename"));
goto Finished;
}
-
+
/* create the file */
- osfd = open( genName, (O_CREAT | O_EXCL | O_RDWR), mode );
- if ( -1 == osfd ) {
- if ( EEXIST == errno ) {
- PR_smprintf_free( genName );
- continue; /* name exists, try again */
- } else {
- _PR_MD_MAP_OPEN_ERROR( errno );
- PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
- ("_md_OpenAnonFileMap(): open(): failed, filename: %s, errno: %d",
- genName, PR_GetOSError()));
- PR_smprintf_free( genName );
- goto Finished;
- }
+ osfd = open(genName, (O_CREAT | O_EXCL | O_RDWR), mode);
+ if (-1 == osfd) {
+ if (EEXIST == errno) {
+ PR_smprintf_free(genName);
+ continue; /* name exists, try again */
+ }
+ _PR_MD_MAP_OPEN_ERROR(errno);
+ PR_LOG(
+ _pr_shma_lm,
+ PR_LOG_DEBUG,
+ ("_md_OpenAnonFileMap(): open(): failed, filename: %s, errno: %d",
+ genName,
+ PR_GetOSError()));
+ PR_smprintf_free(genName);
+ goto Finished;
}
break; /* name generation and open successful, break; */
} /* end for() */
- if ( incr == maxTries ) {
- PR_ASSERT( -1 == osfd );
- PR_ASSERT( EEXIST == errno );
- _PR_MD_MAP_OPEN_ERROR( errno );
- goto Finished;
+ if (incr == maxTries) {
+ PR_ASSERT(-1 == osfd);
+ PR_ASSERT(EEXIST == errno);
+ _PR_MD_MAP_OPEN_ERROR(errno);
+ goto Finished;
}
urc = unlink( genName );
diff --git a/nsprpub/pr/src/md/windows/w32poll.c b/nsprpub/pr/src/md/windows/w32poll.c
index 84100763b..daf14dfe0 100644
--- a/nsprpub/pr/src/md/windows/w32poll.c
+++ b/nsprpub/pr/src/md/windows/w32poll.c
@@ -155,7 +155,7 @@ PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
pd->out_flags = 0; /* pre-condition */
/* make sure this is an NSPR supported stack */
bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
- // ignore a socket without PR_NSPR_IO_LAYER available.
+ /* ignore a socket without PR_NSPR_IO_LAYER available */
if ((NULL != bottom)
&& (_PR_FILEDESC_OPEN == bottom->secret->state))
diff --git a/nsprpub/pr/src/md/windows/w95sock.c b/nsprpub/pr/src/md/windows/w95sock.c
index 1c3ddd911..0429c655a 100644
--- a/nsprpub/pr/src/md/windows/w95sock.c
+++ b/nsprpub/pr/src/md/windows/w95sock.c
@@ -294,8 +294,7 @@ _PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
PRInt32 rv, err;
PRInt32 bytesSent = 0;
- while(bytesSent < amount)
- {
+ do {
while ((rv = sendto( osfd, buf, amount, 0, (struct sockaddr *) addr,
addrlen)) == -1)
{
@@ -327,10 +326,177 @@ _PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
return -1;
}
}
- }
+ } while(bytesSent < amount);
return bytesSent;
}
+#if defined(_WIN64)
+
+static PRCallOnceType _pr_has_connectex_once;
+typedef BOOL (PASCAL FAR * _pr_win_connectex_ptr)(_In_ SOCKET s, _In_reads_bytes_(namelen) const struct sockaddr FAR *name, _In_ int namelen, _In_reads_bytes_opt_(dwSendDataLength) PVOID lpSendBuffer, _In_ DWORD dwSendDataLength, _Out_ LPDWORD lpdwBytesSent, _Inout_ LPOVERLAPPED lpOverlapped);
+
+#ifndef WSAID_CONNECTEX
+#define WSAID_CONNECTEX \
+ {0x25a207b9,0xddf3,0x4660,{0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e}}
+#endif
+#ifndef SIO_GET_EXTENSION_FUNCTION_POINTER
+#define SIO_GET_EXTENSION_FUNCTION_POINTER 0xC8000006
+#endif
+#ifndef TCP_FASTOPEN
+#define TCP_FASTOPEN 15
+#endif
+
+#ifndef SO_UPDATE_CONNECT_CONTEXT
+#define SO_UPDATE_CONNECT_CONTEXT 0x7010
+#endif
+
+static _pr_win_connectex_ptr _pr_win_connectex = NULL;
+
+static PRStatus PR_CALLBACK _pr_set_connectex(void)
+{
+ _pr_win_connectex = NULL;
+ SOCKET sock;
+ PRInt32 dwBytes;
+ int rc;
+
+ /* Dummy socket needed for WSAIoctl */
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock == INVALID_SOCKET)
+ return PR_SUCCESS;
+
+ GUID guid = WSAID_CONNECTEX;
+ rc = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
+ &guid, sizeof(guid),
+ &_pr_win_connectex, sizeof(_pr_win_connectex),
+ &dwBytes, NULL, NULL);
+ if (rc != 0) {
+ _pr_win_connectex = NULL;
+ return PR_SUCCESS;
+ }
+
+ rc = closesocket(sock);
+ return PR_SUCCESS;
+}
+
+PRInt32
+_PR_MD_TCPSENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+ const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
+{
+ if (PR_CallOnce(&_pr_has_connectex_once, _pr_set_connectex) != PR_SUCCESS) {
+ PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+ return PR_FAILURE;
+ }
+
+ if (_pr_win_connectex == NULL) {
+ PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+ return PR_FAILURE;
+ }
+
+ PROsfd osfd = fd->secret->md.osfd;
+ PRInt32 rv, err;
+ PRInt32 bytesSent = 0;
+ DWORD rvSent;
+
+ BOOL option = 1;
+ rv = setsockopt((SOCKET)osfd, IPPROTO_TCP, TCP_FASTOPEN, (char*)&option, sizeof(option));
+ if (rv != 0) {
+ err = WSAGetLastError();
+ PR_LOG(_pr_io_lm, PR_LOG_MIN,
+ ("_PR_MD_TCPSENDTO error set opt TCP_FASTOPEN failed %d\n", err));
+ if (err == WSAENOPROTOOPT) {
+ PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+ } else {
+ _PR_MD_MAP_SETSOCKOPT_ERROR(err);
+ }
+ return -1;
+ }
+
+ /* ConnectEx requires the socket to be initially bound. We will use INADDR_ANY. */
+ PRNetAddr bindAddr;
+ memset(&bindAddr, 0, sizeof(bindAddr));
+ bindAddr.raw.family = addr->raw.family;
+
+ rv = bind((SOCKET)osfd, (const struct sockaddr *)&(bindAddr.inet), PR_NETADDR_SIZE(&bindAddr));
+ if (rv != 0) {
+ err = WSAGetLastError();
+ PR_LOG(_pr_io_lm, PR_LOG_MIN,
+ ("_PR_MD_TCPSENDTO error bind failed %d\n", err));
+ _PR_MD_MAP_SETSOCKOPT_ERROR(err);
+ return -1;
+ }
+
+ PR_LOG(_pr_io_lm, PR_LOG_MIN,
+ ("_PR_MD_TCPSENDTO calling _pr_win_connectex %d %p\n", amount, (char*)buf));
+
+ rvSent = 0;
+ memset(&fd->secret->ol, 0, sizeof(fd->secret->ol));
+ /* ConnectEx return TRUE on a success and FALSE on an error. */
+ if (_pr_win_connectex( (SOCKET)osfd, (struct sockaddr *) addr,
+ addrlen, buf, amount,
+ &rvSent, &fd->secret->ol) == TRUE) {
+ /* 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. */
+ rv = setsockopt((SOCKET)osfd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0);
+ if (rv != 0) {
+ err = WSAGetLastError();
+ PR_LOG(_pr_io_lm, PR_LOG_MIN,
+ ("_PR_MD_TCPSENDTO setting SO_UPDATE_CONNECT_CONTEXT failed %d\n", err));
+ _PR_MD_MAP_SETSOCKOPT_ERROR(err);
+ return -1;
+ }
+ /* We imitate Linux here. SendTo will return number of bytes send but
+ * it can not return connection success at the same time, so we return
+ * number of bytes send and "connection success" will be return on the
+ * connectcontinue. */
+ fd->secret->alreadyConnected = PR_TRUE;
+ return rvSent;
+ } else {
+ err = WSAGetLastError();
+ PR_LOG(_pr_io_lm, PR_LOG_MIN,
+ ("_PR_MD_TCPSENDTO error _pr_win_connectex failed %d\n", err));
+ if (err != ERROR_IO_PENDING) {
+ _PR_MD_MAP_CONNECT_ERROR(err);
+ return -1;
+ } else if (fd->secret->nonblocking) {
+ /* Remember that overlapped structure is set. We will need to get
+ * the final result of ConnectEx call. */
+ fd->secret->overlappedActive = PR_TRUE;
+
+ /* ConnectEx will copy supplied data to a internal buffer and send
+ * them during Fast Open or after connect. Therefore we can assumed
+ * this data already send. */
+ if (amount > 0) {
+ return amount;
+ }
+
+ _PR_MD_MAP_CONNECT_ERROR(WSAEWOULDBLOCK);
+ return -1;
+ }
+ // err is ERROR_IO_PENDING and socket is blocking, so query
+ // GetOverlappedResult.
+ err = ERROR_IO_INCOMPLETE;
+ while (err == ERROR_IO_INCOMPLETE) {
+ rv = socket_io_wait(osfd, WRITE_FD, timeout);
+ if ( rv < 0 ) {
+ return -1;
+ }
+ rv = GetOverlappedResult(osfd, &fd->secret->ol, &rvSent, FALSE);
+ if ( rv == TRUE ) {
+ return rvSent;
+ } else {
+ err = WSAGetLastError();
+ if (err != ERROR_IO_INCOMPLETE) {
+ _PR_MD_MAP_CONNECT_ERROR(err);
+ return -1;
+ }
+ }
+ }
+ }
+ return -1;
+}
+#endif
+
PRInt32
_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
diff --git a/nsprpub/pr/src/misc/praton.c b/nsprpub/pr/src/misc/praton.c
index bff0cd151..80c0628cc 100644
--- a/nsprpub/pr/src/misc/praton.c
+++ b/nsprpub/pr/src/misc/praton.c
@@ -177,19 +177,21 @@ pr_inet_aton(const char *cp, PRUint32 *addr)
case 2: /*%< a.b -- 8.24 bits */
if (val > 0xffffffU)
return (0);
- val |= parts[0] << 24;
+ val |= (unsigned int)parts[0] << 24;
break;
case 3: /*%< a.b.c -- 8.8.16 bits */
if (val > 0xffffU)
return (0);
- val |= (parts[0] << 24) | (parts[1] << 16);
+ val |= ((unsigned int)parts[0] << 24) | ((unsigned int)parts[1] << 16);
break;
case 4: /*%< a.b.c.d -- 8.8.8.8 bits */
if (val > 0xffU)
return (0);
- val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ val |= ((unsigned int)parts[0] << 24) |
+ ((unsigned int)parts[1] << 16) |
+ ((unsigned int)parts[2] << 8);
break;
}
*addr = PR_htonl(val);
diff --git a/nsprpub/pr/src/misc/prnetdb.c b/nsprpub/pr/src/misc/prnetdb.c
index b2f6e435b..affebf6ac 100644
--- a/nsprpub/pr/src/misc/prnetdb.c
+++ b/nsprpub/pr/src/misc/prnetdb.c
@@ -1405,7 +1405,7 @@ PR_IMPLEMENT(PRStatus) PR_InitializeNetAddr(
PRStatus rv = PR_SUCCESS;
if (!_pr_initialized) _PR_ImplicitInitialization();
- if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->inet));
+ if (val != PR_IpAddrNull) memset(addr, 0, sizeof(*addr));
addr->inet.family = AF_INET;
addr->inet.port = htons(port);
switch (val)
@@ -1483,18 +1483,20 @@ PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val)
if (val == PR_IpAddrAny) {
if (_PR_IN6_IS_ADDR_UNSPECIFIED((PRIPv6Addr *)&addr->ipv6.ip)) {
return PR_TRUE;
- } else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
- && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
- == htonl(INADDR_ANY)) {
- return PR_TRUE;
+ }
+ if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
+ && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
+ == htonl(INADDR_ANY)) {
+ return PR_TRUE;
}
} else if (val == PR_IpAddrLoopback) {
if (_PR_IN6_IS_ADDR_LOOPBACK((PRIPv6Addr *)&addr->ipv6.ip)) {
return PR_TRUE;
- } else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
- && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
- == htonl(INADDR_LOOPBACK)) {
- return PR_TRUE;
+ }
+ if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
+ && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
+ == htonl(INADDR_LOOPBACK)) {
+ return PR_TRUE;
}
} else if (val == PR_IpAddrV4Mapped
&& _PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)) {
@@ -1504,8 +1506,9 @@ PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val)
if (addr->raw.family == AF_INET) {
if (val == PR_IpAddrAny && addr->inet.ip == htonl(INADDR_ANY)) {
return PR_TRUE;
- } else if (val == PR_IpAddrLoopback
- && addr->inet.ip == htonl(INADDR_LOOPBACK)) {
+ }
+ if (val == PR_IpAddrLoopback
+ && addr->inet.ip == htonl(INADDR_LOOPBACK)) {
return PR_TRUE;
}
}
@@ -1777,18 +1780,12 @@ PR_IMPLEMENT(PRUint64) PR_ntohll(PRUint64 n)
#ifdef IS_BIG_ENDIAN
return n;
#else
- PRUint64 tmp;
PRUint32 hi, lo;
- LL_L2UI(lo, n);
- LL_SHR(tmp, n, 32);
- LL_L2UI(hi, tmp);
+ lo = (PRUint32)n;
+ hi = (PRUint32)(n >> 32);
hi = PR_ntohl(hi);
lo = PR_ntohl(lo);
- LL_UI2L(n, lo);
- LL_SHL(n, n, 32);
- LL_UI2L(tmp, hi);
- LL_ADD(n, n, tmp);
- return n;
+ return ((PRUint64)lo << 32) + (PRUint64)hi;
#endif
} /* ntohll */
@@ -1797,18 +1794,12 @@ PR_IMPLEMENT(PRUint64) PR_htonll(PRUint64 n)
#ifdef IS_BIG_ENDIAN
return n;
#else
- PRUint64 tmp;
PRUint32 hi, lo;
- LL_L2UI(lo, n);
- LL_SHR(tmp, n, 32);
- LL_L2UI(hi, tmp);
+ lo = (PRUint32)n;
+ hi = (PRUint32)(n >> 32);
hi = htonl(hi);
lo = htonl(lo);
- LL_UI2L(n, lo);
- LL_SHL(n, n, 32);
- LL_UI2L(tmp, hi);
- LL_ADD(n, n, tmp);
- return n;
+ return ((PRUint64)lo << 32) + (PRUint64)hi;
#endif
} /* htonll */
diff --git a/nsprpub/pr/src/misc/prtime.c b/nsprpub/pr/src/misc/prtime.c
index 6735805d8..f03786096 100644
--- a/nsprpub/pr/src/misc/prtime.c
+++ b/nsprpub/pr/src/misc/prtime.c
@@ -279,8 +279,7 @@ static int IsLeapYear(PRInt16 year)
{
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
return 1;
- else
- return 0;
+ return 0;
}
/*
@@ -495,6 +494,20 @@ PR_NormalizeTime(PRExplodedTime *time, PRTimeParamFn params)
#define MT_safe_localtime localtime_r
+#elif defined(_MSC_VER)
+
+/* Visual C++ has had localtime_s() since Visual C++ 2005. */
+
+static struct tm *MT_safe_localtime(const time_t *clock, struct tm *result)
+{
+ errno_t err = localtime_s(result, clock);
+ if (err != 0) {
+ errno = err;
+ return NULL;
+ }
+ return result;
+}
+
#else
#define HAVE_LOCALTIME_MONITOR 1 /* We use 'monitor' to serialize our calls
@@ -580,6 +593,7 @@ PR_LocalTimeParameters(const PRExplodedTime *gmt)
PRTimeParameters retVal;
struct tm localTime;
+ struct tm *localTimeResult;
time_t secs;
PRTime secs64;
PRInt64 usecPerSec;
@@ -606,7 +620,12 @@ PR_LocalTimeParameters(const PRExplodedTime *gmt)
*/
secs = 86400L;
- (void) MT_safe_localtime(&secs, &localTime);
+ localTimeResult = MT_safe_localtime(&secs, &localTime);
+ PR_ASSERT(localTimeResult != NULL);
+ if (localTimeResult == NULL) {
+ /* Shouldn't happen. Use safe fallback for optimized builds. */
+ return PR_GMTParameters(gmt);
+ }
/* GMT is 00:00:00, 2nd of Jan. */
@@ -957,6 +976,7 @@ PR_ParseTimeStringToExplodedTime(
int hour = -1;
int min = -1;
int sec = -1;
+ struct tm *localTimeResult;
const char *rest = string;
@@ -1215,7 +1235,7 @@ PR_ParseTimeStringToExplodedTime(
if ((end - rest) > 2)
/* it is [0-9][0-9][0-9]+: */
break;
- else if ((end - rest) == 2)
+ if ((end - rest) == 2)
tmp_hour = ((rest[0]-'0')*10 +
(rest[1]-'0'));
else
@@ -1230,12 +1250,12 @@ PR_ParseTimeStringToExplodedTime(
if (end == rest)
/* no digits after first colon? */
break;
- else if ((end - rest) > 2)
+ if ((end - rest) > 2)
/* it is [0-9][0-9][0-9]+: */
break;
- else if ((end - rest) == 2)
+ if ((end - rest) == 2)
tmp_min = ((rest[0]-'0')*10 +
- (rest[1]-'0'));
+ (rest[1]-'0'));
else
tmp_min = (rest[0]-'0');
@@ -1253,7 +1273,7 @@ PR_ParseTimeStringToExplodedTime(
else if ((end - rest) > 2)
/* it is [0-9][0-9][0-9]+: */
break;
- else if ((end - rest) == 2)
+ if ((end - rest) == 2)
tmp_sec = ((rest[0]-'0')*10 +
(rest[1]-'0'));
else
@@ -1287,7 +1307,7 @@ PR_ParseTimeStringToExplodedTime(
rest = end;
break;
}
- else if ((*end == '/' || *end == '-') &&
+ if ((*end == '/' || *end == '-') &&
end[1] >= '0' && end[1] <= '9')
{
/* Perhaps this is 6/16/95, 16/6/95, 6-16-95, or 16-6-95
@@ -1618,7 +1638,11 @@ PR_ParseTimeStringToExplodedTime(
zone_offset for the date we are parsing is the same as
the zone offset on 00:00:00 2 Jan 1970 GMT. */
secs = 86400;
- (void) MT_safe_localtime(&secs, &localTime);
+ localTimeResult = MT_safe_localtime(&secs, &localTime);
+ PR_ASSERT(localTimeResult != NULL);
+ if (localTimeResult == NULL) {
+ return PR_FAILURE;
+ }
zone_offset = localTime.tm_min
+ 60 * localTime.tm_hour
+ 1440 * (localTime.tm_mday - 2);
@@ -1989,24 +2013,22 @@ pr_WeekOfYear(const PRExplodedTime* time, unsigned int firstDayOfWeek)
dayOfWeek = time->tm_wday - firstDayOfWeek;
if (dayOfWeek < 0)
dayOfWeek += 7;
-
- dayOfYear = time->tm_yday - dayOfWeek;
+ dayOfYear = time->tm_yday - dayOfWeek;
if( dayOfYear <= 0 )
{
/* If dayOfYear is <= 0, it is in the first partial week of the year. */
return 0;
}
- else
- {
- /* Count the number of full weeks ( dayOfYear / 7 ) then add a week if there
- * are any days left over ( dayOfYear % 7 ). Because we are only counting to
- * the first day of the week containing the given time, rather than to the
- * actual day representing the given time, any days in week 0 will be "absorbed"
- * as extra days in the given week.
- */
- return (dayOfYear / 7) + ( (dayOfYear % 7) == 0 ? 0 : 1 );
- }
+
+ /* Count the number of full weeks ( dayOfYear / 7 ) then add a week if there
+ * are any days left over ( dayOfYear % 7 ). Because we are only counting to
+ * the first day of the week containing the given time, rather than to the
+ * actual day representing the given time, any days in week 0 will be "absorbed"
+ * as extra days in the given week.
+ */
+ return (dayOfYear / 7) + ( (dayOfYear % 7) == 0 ? 0 : 1 );
+
}
diff --git a/nsprpub/pr/src/misc/prtpool.c b/nsprpub/pr/src/misc/prtpool.c
index 0671cc19b..c2cc9c803 100644
--- a/nsprpub/pr/src/misc/prtpool.c
+++ b/nsprpub/pr/src/misc/prtpool.c
@@ -862,16 +862,16 @@ PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod,
if ((rv == PR_FAILURE) && ((err = PR_GetError()) == PR_IN_PROGRESS_ERROR)){
/* connection pending */
return(queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_CONNECT));
- } else {
- /*
- * connection succeeded or failed; add to jobq right away
- */
- if (rv == PR_FAILURE)
- iod->error = err;
- else
- iod->error = 0;
- return(PR_QueueJob(tpool, fn, arg, joinable));
}
+ /*
+ * connection succeeded or failed; add to jobq right away
+ */
+ if (rv == PR_FAILURE)
+ iod->error = err;
+ else
+ iod->error = 0;
+ return(PR_QueueJob(tpool, fn, arg, joinable));
+
}
/* queue a job, when a timer expires */
diff --git a/nsprpub/pr/src/prvrsion.c b/nsprpub/pr/src/prvrsion.c
index 67be53827..be43578ca 100644
--- a/nsprpub/pr/src/prvrsion.c
+++ b/nsprpub/pr/src/prvrsion.c
@@ -74,6 +74,10 @@ static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING
#endif /* XP_UNIX */
+#ifdef _PR_HAS_PRAGMA_DIAGNOSTIC
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint(void)
{
#ifdef XP_UNIX
@@ -88,6 +92,9 @@ PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint(void)
#endif
return &VERSION_DESC_NAME;
} /* versionEntryPointType */
+#ifdef _PR_HAS_PRAGMA_DIAGNOSTIC
+#pragma GCC diagnostic pop
+#endif
/* prvrsion.c */
diff --git a/nsprpub/pr/src/pthreads/ptio.c b/nsprpub/pr/src/pthreads/ptio.c
index e4fe5198b..9dde03191 100644
--- a/nsprpub/pr/src/pthreads/ptio.c
+++ b/nsprpub/pr/src/pthreads/ptio.c
@@ -164,6 +164,9 @@ static ssize_t (*pt_aix_sendfile_fptr)() = NULL;
#ifndef TCP_CORK
#define TCP_CORK 3
#endif
+#ifndef MSG_FASTOPEN
+#define MSG_FASTOPEN 0x20000000
+#endif
#endif
#ifdef _PR_IPV6_V6ONLY_PROBE
@@ -821,7 +824,7 @@ retry:
op->arg3.amount -= bytes; /* and reduce the required count */
return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;
}
- else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
+ if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
{
op->result.code = -1;
return PR_TRUE;
@@ -850,7 +853,7 @@ static PRBool pt_write_cont(pt_Continuation *op, PRInt16 revents)
op->arg3.amount -= bytes; /* and reduce the required count */
return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;
}
- else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
+ if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
{
op->result.code = -1;
return PR_TRUE;
@@ -892,7 +895,7 @@ static PRBool pt_writev_cont(pt_Continuation *op, PRInt16 revents)
op->arg3.amount -= iov_index; /* and array length */
return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;
}
- else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
+ if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
{
op->result.code = -1;
return PR_TRUE;
@@ -915,7 +918,7 @@ static PRBool pt_sendto_cont(pt_Continuation *op, PRInt16 revents)
op->arg3.amount -= bytes; /* and reduce the required count */
return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;
}
- else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
+ if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
{
op->result.code = -1;
return PR_TRUE;
@@ -1542,23 +1545,26 @@ static PRStatus pt_Connect(
pt_SockLen addr_len;
const PRNetAddr *addrp = addr;
#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)
- PRUint16 md_af = addr->raw.family;
PRNetAddr addrCopy;
#endif
+#ifdef _PR_HAVE_SOCKADDR_LEN
+ PRUint16 md_af = addr->raw.family;
+#endif
if (pt_TestAbort()) return PR_FAILURE;
PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
addr_len = PR_NETADDR_SIZE(addr);
-#if defined(_PR_INET6)
- if (addr->raw.family == PR_AF_INET6) {
- md_af = AF_INET6;
-#ifndef _PR_HAVE_SOCKADDR_LEN
- addrCopy = *addr;
- addrCopy.raw.family = AF_INET6;
- addrp = &addrCopy;
+#ifdef _PR_INET6
+ if (addr->raw.family == PR_AF_INET6) {
+#ifdef _PR_HAVE_SOCKADDR_LEN
+ md_af = AF_INET6;
+#else
+ addrCopy = *addr;
+ addrCopy.raw.family = AF_INET6;
+ addrp = &addrCopy;
#endif
- }
+ }
#endif
#ifdef _PR_HAVE_SOCKADDR_LEN
@@ -1732,9 +1738,11 @@ static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *addr)
pt_SockLen addr_len;
const PRNetAddr *addrp = addr;
#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)
- PRUint16 md_af = addr->raw.family;
PRNetAddr addrCopy;
#endif
+#ifdef _PR_HAVE_SOCKADDR_LEN
+ PRUint16 md_af = addr->raw.family;
+#endif
if (pt_TestAbort()) return PR_FAILURE;
@@ -1749,15 +1757,16 @@ static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *addr)
}
}
-#if defined(_PR_INET6)
- if (addr->raw.family == PR_AF_INET6) {
- md_af = AF_INET6;
-#ifndef _PR_HAVE_SOCKADDR_LEN
- addrCopy = *addr;
- addrCopy.raw.family = AF_INET6;
- addrp = &addrCopy;
+#ifdef _PR_INET6
+ if (addr->raw.family == PR_AF_INET6) {
+#ifdef _PR_HAVE_SOCKADDR_LEN
+ md_af = AF_INET6;
+#else
+ addrCopy = *addr;
+ addrCopy.raw.family = AF_INET6;
+ addrp = &addrCopy;
#endif
- }
+ }
#endif
addr_len = PR_NETADDR_SIZE(addr);
@@ -1989,22 +1998,25 @@ static PRInt32 pt_SendTo(
pt_SockLen addr_len;
const PRNetAddr *addrp = addr;
#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)
- PRUint16 md_af = addr->raw.family;
PRNetAddr addrCopy;
#endif
+#ifdef _PR_HAVE_SOCKADDR_LEN
+ PRUint16 md_af = addr->raw.family;
+#endif
if (pt_TestAbort()) return bytes;
PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
-#if defined(_PR_INET6)
- if (addr->raw.family == PR_AF_INET6) {
- md_af = AF_INET6;
-#ifndef _PR_HAVE_SOCKADDR_LEN
- addrCopy = *addr;
- addrCopy.raw.family = AF_INET6;
- addrp = &addrCopy;
+#ifdef _PR_INET6
+ if (addr->raw.family == PR_AF_INET6) {
+#ifdef _PR_HAVE_SOCKADDR_LEN
+ md_af = AF_INET6;
+#else
+ addrCopy = *addr;
+ addrCopy.raw.family = AF_INET6;
+ addrp = &addrCopy;
#endif
- }
+ }
#endif
addr_len = PR_NETADDR_SIZE(addr);
@@ -2044,6 +2056,101 @@ static PRInt32 pt_SendTo(
return bytes;
} /* pt_SendTo */
+#if defined(LINUX) || defined(DARWIN)
+/* Linux uses SendTo to send data during TCP Fast Open. OSX uses connectx, but
+ * we will make it imitate the Linux's interface. */
+static PRInt32 pt_TCP_SendTo(
+ PRFileDesc *fd, const void *buf,
+ PRInt32 amount, PRIntn flags, const PRNetAddr *addr,
+ PRIntervalTime timeout)
+{
+#if defined(LINUX) || HAS_CONNECTX
+ PRInt32 syserrno, bytes = -1;
+ PRBool fNeedContinue = PR_FALSE;
+ pt_SockLen addr_len;
+ const PRNetAddr *addrp = addr;
+#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)
+ PRNetAddr addrCopy;
+#endif
+#ifdef _PR_HAVE_SOCKADDR_LEN
+ PRUint16 md_af = addr->raw.family;
+#endif
+
+ if (pt_TestAbort()) return bytes;
+
+ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+ addr_len = PR_NETADDR_SIZE(addr);
+#if defined(_PR_INET6)
+ if (addr->raw.family == PR_AF_INET6) {
+#ifdef _PR_HAVE_SOCKADDR_LEN
+ md_af = AF_INET6;
+#else
+ /* If _PR_INET6 is defined and it is PR_AF_INET6 we set family
+ * to AF_INET6. */
+ addrCopy = *addr;
+ addrCopy.raw.family = AF_INET6;
+ addrp = &addrCopy;
+#endif
+ }
+#endif
+
+#ifdef _PR_HAVE_SOCKADDR_LEN
+ /* if _PR_HAVE_SOCKADDR_LEN is defined and it is PR_AF_INET6 we set family
+ * to AF_INET6 and we set address length. */
+ addrCopy = *addr;
+ ((struct sockaddr*)&addrCopy)->sa_len = addr_len;
+ ((struct sockaddr*)&addrCopy)->sa_family = md_af;
+ addrp = &addrCopy;
+#endif
+
+#ifndef HAS_CONNECTX
+ bytes = sendto(
+ fd->secret->md.osfd, buf, amount, MSG_FASTOPEN,
+ (struct sockaddr*)addrp, addr_len);
+#else
+ sa_endpoints_t endpoints;
+ endpoints.sae_srcif = 0;
+ endpoints.sae_srcaddr = NULL;
+ endpoints.sae_srcaddrlen = 0;
+ endpoints.sae_dstaddr = (struct sockaddr *)addrp;
+ endpoints.sae_dstaddrlen = addr_len;
+ struct iovec iov[1];
+ iov[0].iov_base = buf;
+ iov[0].iov_len = amount;
+ PRInt32 rv = connectx(fd->secret->md.osfd, &endpoints, SAE_ASSOCID_ANY,
+ CONNECT_DATA_IDEMPOTENT, iov, 1, &bytes, NULL);
+#endif
+ syserrno = errno;
+ if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
+ && (!fd->secret->nonblocking) ) {
+ if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
+ else fNeedContinue = PR_TRUE;
+ }
+ if (fNeedContinue == PR_TRUE) {
+ pt_Continuation op;
+ op.arg1.osfd = fd->secret->md.osfd;
+ op.arg2.buffer = (void*)buf;
+ op.arg3.amount = amount;
+ op.arg4.flags = flags;
+ op.arg5.addr = (PRNetAddr*)addrp;
+ op.timeout = timeout;
+ op.result.code = 0; /* initialize the number sent */
+ op.function = pt_sendto_cont;
+ op.event = POLLOUT | POLLPRI;
+ bytes = pt_Continue(&op);
+ syserrno = op.syserrno;
+ }
+ if (bytes < 0) {
+ pt_MapError(_PR_MD_MAP_SENDTO_ERROR, syserrno);
+ }
+ return bytes;
+#else /* !HAS_CONNECTX */
+ PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+ return -1;
+#endif
+} /* pt_TCP_SendTo */
+#endif /* LINUX || DARWIN */
+
static PRInt32 pt_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,
PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
{
@@ -2767,22 +2874,21 @@ static PRStatus pt_GetSockName(PRFileDesc *fd, PRNetAddr *addr)
if (rv == -1) {
pt_MapError(_PR_MD_MAP_GETSOCKNAME_ERROR, errno);
return PR_FAILURE;
- } else {
+ }
#ifdef _PR_HAVE_SOCKADDR_LEN
- /* ignore the sa_len field of struct sockaddr */
- if (addr)
- {
- addr->raw.family = ((struct sockaddr*)addr)->sa_family;
- }
+ /* ignore the sa_len field of struct sockaddr */
+ if (addr)
+ {
+ addr->raw.family = ((struct sockaddr*)addr)->sa_family;
+ }
#endif /* _PR_HAVE_SOCKADDR_LEN */
#ifdef _PR_INET6
- if (AF_INET6 == addr->raw.family)
- addr->raw.family = PR_AF_INET6;
+ if (AF_INET6 == addr->raw.family)
+ addr->raw.family = PR_AF_INET6;
#endif
- PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
- PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
- return PR_SUCCESS;
- }
+ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+ PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
+ return PR_SUCCESS;
} /* pt_GetSockName */
static PRStatus pt_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
@@ -2798,22 +2904,21 @@ static PRStatus pt_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
if (rv == -1) {
pt_MapError(_PR_MD_MAP_GETPEERNAME_ERROR, errno);
return PR_FAILURE;
- } else {
+ }
#ifdef _PR_HAVE_SOCKADDR_LEN
- /* ignore the sa_len field of struct sockaddr */
- if (addr)
- {
- addr->raw.family = ((struct sockaddr*)addr)->sa_family;
- }
+ /* ignore the sa_len field of struct sockaddr */
+ if (addr)
+ {
+ addr->raw.family = ((struct sockaddr*)addr)->sa_family;
+ }
#endif /* _PR_HAVE_SOCKADDR_LEN */
#ifdef _PR_INET6
- if (AF_INET6 == addr->raw.family)
- addr->raw.family = PR_AF_INET6;
+ if (AF_INET6 == addr->raw.family)
+ addr->raw.family = PR_AF_INET6;
#endif
- PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
- PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
- return PR_SUCCESS;
- }
+ PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+ PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
+ return PR_SUCCESS;
} /* pt_GetPeerName */
static PRStatus pt_GetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
@@ -3155,7 +3260,11 @@ static PRIOMethods _pr_tcp_methods = {
pt_Recv,
pt_Send,
(PRRecvfromFN)_PR_InvalidInt,
+#if defined(LINUX) || defined(DARWIN)
+ pt_TCP_SendTo, /* This is for TCP Fast Open. Linux uses SendTo function for this. OSX uses connectx, but we imitate Linux. */
+#else
(PRSendtoFN)_PR_InvalidInt,
+#endif
pt_Poll,
pt_AcceptRead,
pt_TransmitFile,
@@ -3602,8 +3711,8 @@ PR_IMPLEMENT(PRStatus) PR_Delete(const char *name)
if (rv == -1) {
pt_MapError(_PR_MD_MAP_UNLINK_ERROR, errno);
return PR_FAILURE;
- } else
- return PR_SUCCESS;
+ }
+ return PR_SUCCESS;
} /* PR_Delete */
PR_IMPLEMENT(PRStatus) PR_Access(const char *name, PRAccessHow how)
@@ -3727,11 +3836,10 @@ PR_IMPLEMENT(PRStatus) PR_RmDir(const char *name)
rv = rmdir(name);
if (0 == rv) {
- return PR_SUCCESS;
- } else {
+ return PR_SUCCESS;
+ }
pt_MapError(_PR_MD_MAP_RMDIR_ERROR, errno);
return PR_FAILURE;
- }
} /* PR_Rmdir */
@@ -3847,7 +3955,8 @@ static PRInt32 _pr_poll_with_poll(
/* now locate the NSPR layer at the bottom of the stack */
PRFileDesc *bottom = PR_GetIdentitiesLayer(
pds[index].fd, PR_NSPR_IO_LAYER);
- PR_ASSERT(NULL != bottom); /* what to do about that? */
+ /* ignore a socket without PR_NSPR_IO_LAYER available */
+
pds[index].out_flags = 0; /* pre-condition */
if ((NULL != bottom)
&& (_PR_FILEDESC_OPEN == bottom->secret->state))
@@ -4105,7 +4214,8 @@ static PRInt32 _pr_poll_with_select(
/* now locate the NSPR layer at the bottom of the stack */
PRFileDesc *bottom = PR_GetIdentitiesLayer(
pds[index].fd, PR_NSPR_IO_LAYER);
- PR_ASSERT(NULL != bottom); /* what to do about that? */
+ /* ignore a socket without PR_NSPR_IO_LAYER available */
+
pds[index].out_flags = 0; /* pre-condition */
if ((NULL != bottom)
&& (_PR_FILEDESC_OPEN == bottom->secret->state))
diff --git a/nsprpub/pr/src/pthreads/ptsynch.c b/nsprpub/pr/src/pthreads/ptsynch.c
index 8663a4c71..251205336 100644
--- a/nsprpub/pr/src/pthreads/ptsynch.c
+++ b/nsprpub/pr/src/pthreads/ptsynch.c
@@ -55,12 +55,11 @@ void _PR_InitLocks(void)
rv = _PT_PTHREAD_MUTEXATTR_INIT(&_pt_mattr);
PR_ASSERT(0 == rv);
-#ifdef LINUX
-#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)
+#if (defined(LINUX) && (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) || \
+ (defined(FREEBSD) && __FreeBSD_version > 700055)
rv = pthread_mutexattr_settype(&_pt_mattr, PTHREAD_MUTEX_ADAPTIVE_NP);
PR_ASSERT(0 == rv);
#endif
-#endif
rv = _PT_PTHREAD_CONDATTR_INIT(&_pt_cvar_attr);
PR_ASSERT(0 == rv);