diff options
Diffstat (limited to 'nsprpub/pr')
25 files changed, 691 insertions, 242 deletions
diff --git a/nsprpub/pr/include/md/_linux.cfg b/nsprpub/pr/include/md/_linux.cfg index 8cbf0cb9b2..b4c0ed427b 100644 --- a/nsprpub/pr/include/md/_linux.cfg +++ b/nsprpub/pr/include/md/_linux.cfg @@ -498,6 +498,9 @@ #elif defined(__mips__) +/* For _ABI64 */ +#include <sgidefs.h> + #ifdef __MIPSEB__ #define IS_BIG_ENDIAN 1 #undef IS_LITTLE_ENDIAN diff --git a/nsprpub/pr/include/md/_win95.h b/nsprpub/pr/include/md/_win95.h index d65e264376..04f811d37d 100644 --- a/nsprpub/pr/include/md/_win95.h +++ b/nsprpub/pr/include/md/_win95.h @@ -290,6 +290,9 @@ extern void _MD_MakeNonblock(PRFileDesc *f); extern PRInt32 _MD_CloseSocket(PROsfd osfd); #define _MD_CLOSE_SOCKET _MD_CloseSocket #define _MD_SENDTO _PR_MD_SENDTO +#ifdef _WIN64 +#define _MD_TCPSENDTO _PR_MD_TCPSENDTO +#endif #define _MD_RECVFROM _PR_MD_RECVFROM #define _MD_SOCKETPAIR(s, type, proto, sv) -1 #define _MD_GETSOCKNAME _PR_MD_GETSOCKNAME diff --git a/nsprpub/pr/include/prinit.h b/nsprpub/pr/include/prinit.h index e27fc34d05..fd935ec309 100644 --- a/nsprpub/pr/include/prinit.h +++ b/nsprpub/pr/include/prinit.h @@ -31,10 +31,10 @@ PR_BEGIN_EXTERN_C ** The format of the version string is ** "<major version>.<minor version>[.<patch level>] [<Beta>]" */ -#define PR_VERSION "4.13.1" +#define PR_VERSION "4.16" #define PR_VMAJOR 4 -#define PR_VMINOR 13 -#define PR_VPATCH 1 +#define PR_VMINOR 16 +#define PR_VPATCH 0 #define PR_BETA PR_FALSE /* diff --git a/nsprpub/pr/include/private/primpl.h b/nsprpub/pr/include/private/primpl.h index 63ba3ee46f..dc24a25727 100644 --- a/nsprpub/pr/include/private/primpl.h +++ b/nsprpub/pr/include/private/primpl.h @@ -1225,6 +1225,13 @@ extern PRInt32 _PR_MD_SENDTO( const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout); #define _PR_MD_SENDTO _MD_SENDTO +#if defined(_WIN64) && defined(WIN95) +extern PRInt32 _PR_MD_TCPSENDTO( + PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, + const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout); +#define _PR_MD_TCPSENDTO _MD_TCPSENDTO +#endif + extern PRInt32 _PR_MD_SOCKETPAIR(int af, int type, int flags, PROsfd *osfd); #define _PR_MD_SOCKETPAIR _MD_SOCKETPAIR @@ -1747,6 +1754,18 @@ struct PRFilePrivate { * requires knowing the address family of the * socket, we save the address family here. */ #endif + +#if defined(_WIN64) + /* This is necessary for TCP Fast Open. TCP Fast Open in windows must + * use ConnectEx function which uses OVERLAPPED. TCPSendTo will call + * ConnectEx to send fast open data. If ConnectEx returns + * ERROR_IO_PENDING we need to save OVERLAPPED structure and we will + * use it in ConnectContinue to get the final result of ConnectEx. + */ + PRBool alreadyConnected; + PRBool overlappedActive; + OVERLAPPED ol; +#endif }; #ifdef _WIN64 diff --git a/nsprpub/pr/include/prtypes.h b/nsprpub/pr/include/prtypes.h index 52b3ab0b19..94bca3cfcd 100644 --- a/nsprpub/pr/include/prtypes.h +++ b/nsprpub/pr/include/prtypes.h @@ -231,7 +231,7 @@ PR_BEGIN_EXTERN_C ** to use <stdint.h>. A patch to do that is in NSPR bug 634793. */ -#if defined(__APPLE__) || defined(__ANDROID__) || defined(__OpenBSD__) +#if defined(__APPLE__) || defined(__OpenBSD__) #define PR_ALTERNATE_INT64_TYPEDEF #endif @@ -245,16 +245,24 @@ PR_BEGIN_EXTERN_C #if PR_BYTES_PER_BYTE == 1 typedef unsigned char PRUint8; /* +** There are two scenarios that require us to define PRInt8 as type 'char'. +** (1) ** Some cfront-based C++ compilers do not like 'signed char' and ** issue the warning message: ** warning: "signed" not implemented (ignored) ** For these compilers, we have to define PRInt8 as plain 'char'. ** Make sure that plain 'char' is indeed signed under these compilers. +** (2) +** Mozilla C++ code expects the PRInt{N} and int{N}_t types to match (see bug +** 634793). If a platform defines int8_t as 'char', but NSPR defines it as +** 'signed char', it results in a type mismatch. +** On such platforms we define PRInt8 as 'char' to avoid the mismatch. */ -#if (defined(HPUX) && defined(__cplusplus) \ +#if (defined(HPUX) && defined(__cplusplus) /* reason 1*/ \ && !defined(__GNUC__) && __cplusplus < 199707L) \ - || (defined(SCO) && defined(__cplusplus) \ - && !defined(__GNUC__) && __cplusplus == 1L) + || (defined(SCO) && defined(__cplusplus) /* reason 1 */ \ + && !defined(__GNUC__) && __cplusplus == 1L) \ + || (defined(__sun) && defined(__cplusplus)) /* reason 2 */ typedef char PRInt8; #else typedef signed char PRInt8; diff --git a/nsprpub/pr/src/io/prio.c b/nsprpub/pr/src/io/prio.c index 78cbdf564b..bf9763a2cd 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 cadb7ca3ca..00da0287a1 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 6ffc133056..64f7ed4e83 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 9d75d824e8..377a6e6436 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 be97024080..a24b8e1bb4 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 fdae1199ce..662f561b6f 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 a3b35e540b..5286b9e185 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 dec4e3a7af..54e68191cd 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 84100763b0..daf14dfe05 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 1c3ddd9110..0429c655aa 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 bff0cd1513..80c0628cc2 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 b2f6e435b5..affebf6ac3 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 6735805d81..f037860967 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 0671cc19b1..c2cc9c8039 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 67be53827a..be43578ca7 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 e4fe5198bb..9dde031912 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 8663a4c719..251205336b 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); diff --git a/nsprpub/pr/tests/accept.c b/nsprpub/pr/tests/accept.c index 7ed2d98595..b327eb2114 100644 --- a/nsprpub/pr/tests/accept.c +++ b/nsprpub/pr/tests/accept.c @@ -143,12 +143,13 @@ ClientThread(void *_action) if (action != CLIENT_TIMEOUT_SEND) { if ((rv = PR_Send(sock, buf, CLIENT_DATA, 0, timeoutTime))< 0) { - if (!debug_mode) + if (!debug_mode) { failed_already=1; - else - PR_fprintf(output, + } else { + PR_fprintf(output, "client: unable to send to server (%d, %ld, %ld)\n", CLIENT_DATA, rv, PR_GetError()); + } goto ErrorExit; } } else { @@ -200,8 +201,9 @@ int i; continue; } failed_already=1; - if (debug_mode) + if (debug_mode) { PR_fprintf(output,"accept: ERROR - PR_Bind failed\n"); + } return; } diff --git a/nsprpub/pr/tests/alarm.c b/nsprpub/pr/tests/alarm.c index b7b1958016..e3dedb67fc 100644 --- a/nsprpub/pr/tests/alarm.c +++ b/nsprpub/pr/tests/alarm.c @@ -411,15 +411,15 @@ static PRUint32 TimeThis( PRUint32 overhead, usecs; PRIntervalTime predicted, timein, timeout, ticks; - if (debug_mode) - printf("Testing %s ...", msg); + if (debug_mode) + printf("Testing %s ...", msg); timein = PR_IntervalNow(); predicted = func(loops); timeout = PR_IntervalNow(); - if (debug_mode) - printf(" done\n"); + if (debug_mode) + printf(" done\n"); ticks = timeout - timein; usecs = PR_IntervalToMicroseconds(ticks); @@ -491,17 +491,17 @@ int prmain(int argc, char** argv) for (cpu = 1; cpu <= cpus; ++cpu) { - if (debug_mode) + if (debug_mode) printf("\nAlarm: Using %d CPU(s)\n", cpu); - PR_SetConcurrency(cpu); - - /* some basic time test */ - (void)TimeThis("ConditionNotify", ConditionNotify, loops); - (void)TimeThis("ConditionTimeout", ConditionTimeout, loops); - (void)TimeThis("Alarms1", Alarms1, loops); - (void)TimeThis("Alarms2", Alarms2, loops); - (void)TimeThis("Alarms3", Alarms3, loops); + PR_SetConcurrency(cpu); + + /* some basic time test */ + (void)TimeThis("ConditionNotify", ConditionNotify, loops); + (void)TimeThis("ConditionTimeout", ConditionTimeout, loops); + (void)TimeThis("Alarms1", Alarms1, loops); + (void)TimeThis("Alarms2", Alarms2, loops); + (void)TimeThis("Alarms3", Alarms3, loops); } return 0; } diff --git a/nsprpub/pr/tests/vercheck.c b/nsprpub/pr/tests/vercheck.c index 6cb4eb2db5..6170125dea 100644 --- a/nsprpub/pr/tests/vercheck.c +++ b/nsprpub/pr/tests/vercheck.c @@ -39,7 +39,7 @@ static char *compatible_version[] = { "4.9.6", "4.10", "4.10.1", "4.10.2", "4.10.3", "4.10.4", "4.10.5", "4.10.6", "4.10.7", "4.10.8", "4.10.9", - "4.10.10", "4.11", "4.12", "4.13", + "4.10.10", "4.11", "4.12", "4.13", "4.14", "4.15" PR_VERSION }; @@ -55,8 +55,8 @@ static char *incompatible_version[] = { "3.0", "3.0.1", "3.1", "3.1.1", "3.1.2", "3.1.3", "3.5", "3.5.1", - "4.13.2", - "4.14", "4.14.1", + "4.16.1", + "4.17", "4.17.1", "10.0", "11.1", "12.14.20" }; |