mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-20 07:17:32 +09:00
Update NSPR to 4.16
This commit is contained in:
parent
fd1bb58ea8
commit
f29876f120
31 changed files with 811 additions and 247 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -55,11 +55,10 @@ 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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue