Update NSPR to 4.16

This commit is contained in:
wolfbeast 2018-02-06 11:40:35 +01:00 • committed by Roy Tam
commit f29876f120
31 changed files with 811 additions and 247 deletions

View file

@ -1 +1 @@
NSPR_4_13_1_RTM NSPR_4_16_RTM

53
nsprpub/configure vendored
View file

@ -2488,8 +2488,8 @@ test -n "$target_alias" &&
program_prefix=${target_alias}- program_prefix=${target_alias}-
MOD_MAJOR_VERSION=4 MOD_MAJOR_VERSION=4
MOD_MINOR_VERSION=13 MOD_MINOR_VERSION=16
MOD_PATCH_VERSION=1 MOD_PATCH_VERSION=0
NSPR_MODNAME=nspr20 NSPR_MODNAME=nspr20
_HAVE_PTHREADS= _HAVE_PTHREADS=
USE_PTHREADS= USE_PTHREADS=
@ -5424,6 +5424,40 @@ $as_echo "no" >&6; }
fi fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pragma diagnostic" >&5
$as_echo_n "checking for pragma diagnostic... " >&6; }
if test "$GNU_CC" = "1"; then
cat >dummy-hello.c <<EOF
#ifdef _PR_HAS_PRAGMA_DIAGNOSTIC
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#endif
int main() {
char *dummy = "";
return 0;
}
EOF
${CC} -Werror=unused-but-set-variable -S dummy-hello.c -o dummy-hello.s 2>&5
if test $? != 0; then
${CC} -Werror=unused-but-set-variable -D_PR_HAS_PRAGMA_DIAGNOSTIC -S dummy-hello.c -o dummy-hello.s 2>&5
if test $? = 0; then
CFLAGS="$CFLAGS -D_PR_HAS_PRAGMA_DIAGNOSTIC=1"
_res=yes
else
_res=no
fi
else
_res=no
fi
rm -f dummy-hello.c dummy-hello.s
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_res" >&5
$as_echo "$_res" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
_SAVE_CFLAGS="$CFLAGS" _SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -fprofile-generate -fprofile-correction" CFLAGS="$CFLAGS -fprofile-generate -fprofile-correction"
@ -6524,6 +6558,13 @@ fi
$as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h $as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h
$as_echo "#define HAVE_POINTER_LOCALTIME_R 1" >>confdefs.h
HOST_DARWIN_MAJOR=`echo "$build_os" | sed -E -e 's/^darwin([0-9]+).*$/\1/'`
if test "$HOST_DARWIN_MAJOR" -ge 15 ; then
$as_echo "#define HAS_CONNECTX 1" >>confdefs.h
fi
AS='$(CC) -x assembler-with-cpp' AS='$(CC) -x assembler-with-cpp'
CFLAGS="$CFLAGS -Wall -fno-common" CFLAGS="$CFLAGS -Wall -fno-common"
case "${target_cpu}" in case "${target_cpu}" in
@ -6673,6 +6714,8 @@ tools are selected during the Xcode/Developer Tools installation." "$LINENO" 5
$as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h $as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h
$as_echo "#define HAVE_POINTER_LOCALTIME_R 1" >>confdefs.h
CFLAGS="$CFLAGS $(DSO_CFLAGS) -ansi -Wall" CFLAGS="$CFLAGS $(DSO_CFLAGS) -ansi -Wall"
MOZ_OBJFORMAT=`test -x /usr/bin/objformat && /usr/bin/objformat || echo elf` MOZ_OBJFORMAT=`test -x /usr/bin/objformat && /usr/bin/objformat || echo elf`
if test "$MOZ_OBJFORMAT" = "elf"; then if test "$MOZ_OBJFORMAT" = "elf"; then
@ -6975,6 +7018,8 @@ tools are selected during the Xcode/Developer Tools installation." "$LINENO" 5
$as_echo "#define HAVE_FCNTL_FILE_LOCKING 1" >>confdefs.h $as_echo "#define HAVE_FCNTL_FILE_LOCKING 1" >>confdefs.h
$as_echo "#define HAVE_POINTER_LOCALTIME_R 1" >>confdefs.h
case "${target}" in case "${target}" in
*-android*|*-linuxandroid*) *-android*|*-linuxandroid*)
OS_TARGET=Android OS_TARGET=Android
@ -7281,6 +7326,8 @@ $as_echo "$as_me: WARNING: Unknown version of the Microsoft (R) Manifest Tool."
$as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h $as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h
$as_echo "#define HAVE_POINTER_LOCALTIME_R 1" >>confdefs.h
if test -z "$USE_NSPR_THREADS"; then if test -z "$USE_NSPR_THREADS"; then
USE_PTHREADS=1 USE_PTHREADS=1
fi fi
@ -7337,6 +7384,8 @@ $as_echo "$as_me: WARNING: Unknown version of the Microsoft (R) Manifest Tool."
$as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h $as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h
$as_echo "#define HAVE_POINTER_LOCALTIME_R 1" >>confdefs.h
CFLAGS="$CFLAGS -ansi -Wall" CFLAGS="$CFLAGS -ansi -Wall"
CXXFLAGS="$CXXFLAGS -ansi -Wall" CXXFLAGS="$CXXFLAGS -ansi -Wall"
DLL_SUFFIX=so.1.0 DLL_SUFFIX=so.1.0

View file

@ -15,8 +15,8 @@ dnl ========================================================
dnl = Defaults dnl = Defaults
dnl ======================================================== dnl ========================================================
MOD_MAJOR_VERSION=4 MOD_MAJOR_VERSION=4
MOD_MINOR_VERSION=13 MOD_MINOR_VERSION=16
MOD_PATCH_VERSION=1 MOD_PATCH_VERSION=0
NSPR_MODNAME=nspr20 NSPR_MODNAME=nspr20
_HAVE_PTHREADS= _HAVE_PTHREADS=
USE_PTHREADS= USE_PTHREADS=
@ -715,6 +715,40 @@ else
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
fi fi
dnl ========================================================
dnl Check for pragma diagnostic
dnl ========================================================
AC_MSG_CHECKING([for pragma diagnostic])
if test "$GNU_CC" = "1"; then
cat >dummy-hello.c <<EOF
#ifdef _PR_HAS_PRAGMA_DIAGNOSTIC
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#endif
int main() {
char *dummy = "";
return 0;
}
EOF
${CC} -Werror=unused-but-set-variable -S dummy-hello.c -o dummy-hello.s 2>&5
if test $? != 0; then
${CC} -Werror=unused-but-set-variable -D_PR_HAS_PRAGMA_DIAGNOSTIC -S dummy-hello.c -o dummy-hello.s 2>&5
if test $? = 0; then
CFLAGS="$CFLAGS -D_PR_HAS_PRAGMA_DIAGNOSTIC=1"
_res=yes
else
_res=no
fi
else
_res=no
fi
rm -f dummy-hello.c dummy-hello.s
AC_MSG_RESULT([$_res])
else
AC_MSG_RESULT([no])
fi
dnl ======================================================== dnl ========================================================
dnl Profile guided optimization dnl Profile guided optimization
dnl ======================================================== dnl ========================================================
@ -1349,6 +1383,13 @@ case "$target" in
AC_DEFINE(DARWIN) AC_DEFINE(DARWIN)
AC_DEFINE(HAVE_BSD_FLOCK) AC_DEFINE(HAVE_BSD_FLOCK)
AC_DEFINE(HAVE_SOCKLEN_T) AC_DEFINE(HAVE_SOCKLEN_T)
AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
changequote(,)
HOST_DARWIN_MAJOR=`echo "$build_os" | sed -E -e 's/^darwin([0-9]+).*$/\1/'`
changequote([,])
if test "$HOST_DARWIN_MAJOR" -ge 15 ; then
AC_DEFINE(HAS_CONNECTX)
fi
AS='$(CC) -x assembler-with-cpp' AS='$(CC) -x assembler-with-cpp'
CFLAGS="$CFLAGS -Wall -fno-common" CFLAGS="$CFLAGS -Wall -fno-common"
case "${target_cpu}" in case "${target_cpu}" in
@ -1519,6 +1560,7 @@ tools are selected during the Xcode/Developer Tools installation.])
AC_DEFINE(FREEBSD) AC_DEFINE(FREEBSD)
AC_DEFINE(HAVE_BSD_FLOCK) AC_DEFINE(HAVE_BSD_FLOCK)
AC_DEFINE(HAVE_SOCKLEN_T) AC_DEFINE(HAVE_SOCKLEN_T)
AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
CFLAGS="$CFLAGS $(DSO_CFLAGS) -ansi -Wall" CFLAGS="$CFLAGS $(DSO_CFLAGS) -ansi -Wall"
MOZ_OBJFORMAT=`test -x /usr/bin/objformat && /usr/bin/objformat || echo elf` MOZ_OBJFORMAT=`test -x /usr/bin/objformat && /usr/bin/objformat || echo elf`
if test "$MOZ_OBJFORMAT" = "elf"; then if test "$MOZ_OBJFORMAT" = "elf"; then
@ -1789,6 +1831,7 @@ tools are selected during the Xcode/Developer Tools installation.])
AC_DEFINE(XP_UNIX) AC_DEFINE(XP_UNIX)
AC_DEFINE(_GNU_SOURCE) AC_DEFINE(_GNU_SOURCE)
AC_DEFINE(HAVE_FCNTL_FILE_LOCKING) AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
case "${target}" in case "${target}" in
*-android*|*-linuxandroid*) *-android*|*-linuxandroid*)
OS_TARGET=Android OS_TARGET=Android
@ -2078,6 +2121,7 @@ tools are selected during the Xcode/Developer Tools installation.])
AC_DEFINE(NETBSD) AC_DEFINE(NETBSD)
AC_DEFINE(HAVE_BSD_FLOCK) AC_DEFINE(HAVE_BSD_FLOCK)
AC_DEFINE(HAVE_SOCKLEN_T) AC_DEFINE(HAVE_SOCKLEN_T)
AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
if test -z "$USE_NSPR_THREADS"; then if test -z "$USE_NSPR_THREADS"; then
USE_PTHREADS=1 USE_PTHREADS=1
fi fi
@ -2126,6 +2170,7 @@ tools are selected during the Xcode/Developer Tools installation.])
AC_DEFINE(OPENBSD) AC_DEFINE(OPENBSD)
AC_DEFINE(HAVE_BSD_FLOCK) AC_DEFINE(HAVE_BSD_FLOCK)
AC_DEFINE(HAVE_SOCKLEN_T) AC_DEFINE(HAVE_SOCKLEN_T)
AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
CFLAGS="$CFLAGS -ansi -Wall" CFLAGS="$CFLAGS -ansi -Wall"
CXXFLAGS="$CXXFLAGS -ansi -Wall" CXXFLAGS="$CXXFLAGS -ansi -Wall"
DLL_SUFFIX=so.1.0 DLL_SUFFIX=so.1.0

View file

@ -74,6 +74,10 @@ static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING
#endif /* XP_UNIX */ #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() PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
{ {
#ifdef XP_UNIX #ifdef XP_UNIX
@ -88,6 +92,9 @@ PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
#endif #endif
return &VERSION_DESC_NAME; return &VERSION_DESC_NAME;
} /* versionEntryPointType */ } /* versionEntryPointType */
#ifdef _PR_HAS_PRAGMA_DIAGNOSTIC
#pragma GCC diagnostic pop
#endif
/* plvrsion.c */ /* plvrsion.c */

View file

@ -74,6 +74,10 @@ static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING
#endif /* XP_UNIX */ #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() PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
{ {
#ifdef XP_UNIX #ifdef XP_UNIX
@ -88,6 +92,9 @@ PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
#endif #endif
return &VERSION_DESC_NAME; return &VERSION_DESC_NAME;
} /* versionEntryPointType */ } /* versionEntryPointType */
#ifdef _PR_HAS_PRAGMA_DIAGNOSTIC
#pragma GCC diagnostic pop
#endif
/* plvrsion.c */ /* plvrsion.c */

View file

@ -74,6 +74,10 @@ static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING
#endif /* XP_UNIX */ #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() PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
{ {
#ifdef XP_UNIX #ifdef XP_UNIX
@ -88,6 +92,9 @@ PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
#endif #endif
return &VERSION_DESC_NAME; return &VERSION_DESC_NAME;
} /* versionEntryPointType */ } /* versionEntryPointType */
#ifdef _PR_HAS_PRAGMA_DIAGNOSTIC
#pragma GCC diagnostic pop
#endif
/* plvrsion.c */ /* plvrsion.c */

View file

@ -498,6 +498,9 @@
#elif defined(__mips__) #elif defined(__mips__)
/* For _ABI64 */
#include <sgidefs.h>
#ifdef __MIPSEB__ #ifdef __MIPSEB__
#define IS_BIG_ENDIAN 1 #define IS_BIG_ENDIAN 1
#undef IS_LITTLE_ENDIAN #undef IS_LITTLE_ENDIAN

View file

@ -290,6 +290,9 @@ extern void _MD_MakeNonblock(PRFileDesc *f);
extern PRInt32 _MD_CloseSocket(PROsfd osfd); extern PRInt32 _MD_CloseSocket(PROsfd osfd);
#define _MD_CLOSE_SOCKET _MD_CloseSocket #define _MD_CLOSE_SOCKET _MD_CloseSocket
#define _MD_SENDTO _PR_MD_SENDTO #define _MD_SENDTO _PR_MD_SENDTO
#ifdef _WIN64
#define _MD_TCPSENDTO _PR_MD_TCPSENDTO
#endif
#define _MD_RECVFROM _PR_MD_RECVFROM #define _MD_RECVFROM _PR_MD_RECVFROM
#define _MD_SOCKETPAIR(s, type, proto, sv) -1 #define _MD_SOCKETPAIR(s, type, proto, sv) -1
#define _MD_GETSOCKNAME _PR_MD_GETSOCKNAME #define _MD_GETSOCKNAME _PR_MD_GETSOCKNAME

View file

@ -31,10 +31,10 @@ PR_BEGIN_EXTERN_C
** The format of the version string is ** The format of the version string is
** "<major version>.<minor version>[.<patch level>] [<Beta>]" ** "<major version>.<minor version>[.<patch level>] [<Beta>]"
*/ */
#define PR_VERSION "4.13.1" #define PR_VERSION "4.16"
#define PR_VMAJOR 4 #define PR_VMAJOR 4
#define PR_VMINOR 13 #define PR_VMINOR 16
#define PR_VPATCH 1 #define PR_VPATCH 0
#define PR_BETA PR_FALSE #define PR_BETA PR_FALSE
/* /*

View file

@ -1225,6 +1225,13 @@ extern PRInt32 _PR_MD_SENDTO(
const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout); const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout);
#define _PR_MD_SENDTO _MD_SENDTO #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); extern PRInt32 _PR_MD_SOCKETPAIR(int af, int type, int flags, PROsfd *osfd);
#define _PR_MD_SOCKETPAIR _MD_SOCKETPAIR #define _PR_MD_SOCKETPAIR _MD_SOCKETPAIR
@ -1747,6 +1754,18 @@ struct PRFilePrivate {
* requires knowing the address family of the * requires knowing the address family of the
* socket, we save the address family here. */ * socket, we save the address family here. */
#endif #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 #ifdef _WIN64

View file

@ -231,7 +231,7 @@ PR_BEGIN_EXTERN_C
** to use <stdint.h>. A patch to do that is in NSPR bug 634793. ** 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 #define PR_ALTERNATE_INT64_TYPEDEF
#endif #endif
@ -245,16 +245,24 @@ PR_BEGIN_EXTERN_C
#if PR_BYTES_PER_BYTE == 1 #if PR_BYTES_PER_BYTE == 1
typedef unsigned char PRUint8; 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 ** Some cfront-based C++ compilers do not like 'signed char' and
** issue the warning message: ** issue the warning message:
** warning: "signed" not implemented (ignored) ** warning: "signed" not implemented (ignored)
** For these compilers, we have to define PRInt8 as plain 'char'. ** For these compilers, we have to define PRInt8 as plain 'char'.
** Make sure that plain 'char' is indeed signed under these compilers. ** 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(__GNUC__) && __cplusplus < 199707L) \
|| (defined(SCO) && defined(__cplusplus) \ || (defined(SCO) && defined(__cplusplus) /* reason 1 */ \
&& !defined(__GNUC__) && __cplusplus == 1L) && !defined(__GNUC__) && __cplusplus == 1L) \
|| (defined(__sun) && defined(__cplusplus)) /* reason 2 */
typedef char PRInt8; typedef char PRInt8;
#else #else
typedef signed char PRInt8; typedef signed char PRInt8;

View file

@ -119,6 +119,10 @@ PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(
fd->methods = methods; fd->methods = methods;
fd->secret->state = _PR_FILEDESC_OPEN; fd->secret->state = _PR_FILEDESC_OPEN;
fd->secret->md.osfd = osfd; fd->secret->md.osfd = osfd;
#if defined(_WIN64)
fd->secret->alreadyConnected = PR_FALSE;
fd->secret->overlappedActive = PR_FALSE;
#endif
_PR_MD_INIT_FILEDESC(fd); _PR_MD_INIT_FILEDESC(fd);
} else { } else {
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);

View file

@ -47,7 +47,8 @@ static PRStatus PR_CALLBACK pl_TopClose (PRFileDesc *fd)
rv = fd->lower->methods->close(fd->lower); rv = fd->lower->methods->close(fd->lower);
_PR_DestroyIOLayer(fd); _PR_DestroyIOLayer(fd);
return rv; 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 * lower layers of new style stack
*/ */
@ -201,16 +202,16 @@ static PRFileDesc* PR_CALLBACK pl_TopAccept (
return NULL; return NULL;
} }
if (newstyle_stack) { if (newstyle_stack)
newstack->lower = newfd; {
newfd->higher = newstack; newstack->lower = newfd;
return newstack; newfd->higher = newstack;
} else { return newstack;
/* this PR_PushIOLayer call cannot fail */ }
rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack); /* this PR_PushIOLayer call cannot fail */
PR_ASSERT(PR_SUCCESS == rv); rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);
return newfd; /* that's it */ PR_ASSERT(PR_SUCCESS == rv);
} return newfd; /* that's it */
} }
static PRStatus PR_CALLBACK pl_DefBind (PRFileDesc *fd, const PRNetAddr *addr) 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)->higher = newstack;
*nd = newstack; *nd = newstack;
return nbytes; 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 ( static PRInt32 PR_CALLBACK pl_DefTransmitfile (
@ -494,10 +494,9 @@ static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack)
{ {
if (NULL == stack) if (NULL == stack)
return PR_FAILURE; return PR_FAILURE;
else {
PR_DELETE(stack); PR_DELETE(stack);
return PR_SUCCESS; return PR_SUCCESS;
}
} /* _PR_DestroyIOLayer */ } /* _PR_DestroyIOLayer */
PR_IMPLEMENT(PRStatus) PR_PushIOLayer( PR_IMPLEMENT(PRStatus) PR_PushIOLayer(
@ -652,9 +651,11 @@ retry:
if ((NULL != names) && (identity < length)) if ((NULL != names) && (identity < length))
{ {
/* what we did is still okay */ /* what we did is still okay */
memcpy( if (identity_cache.length != 0) {
names, identity_cache.name, memcpy(
identity_cache.length * sizeof(char*)); names, identity_cache.name,
identity_cache.length * sizeof(char*));
}
old = identity_cache.name; old = identity_cache.name;
identity_cache.name = names; identity_cache.name = names;
identity_cache.length = length; identity_cache.length = length;
@ -702,8 +703,8 @@ PR_IMPLEMENT(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd)
if (PR_IO_LAYER_HEAD == fd->identity) { if (PR_IO_LAYER_HEAD == fd->identity) {
PR_ASSERT(NULL != fd->lower); PR_ASSERT(NULL != fd->lower);
return fd->lower->identity; return fd->lower->identity;
} else }
return fd->identity; return fd->identity;
} /* PR_GetLayersIdentity */ } /* PR_GetLayersIdentity */
PR_IMPLEMENT(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd, PRDescIdentity id) 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; PRFileDesc *layer = fd;
if (PR_TOP_IO_LAYER == id) { if (PR_TOP_IO_LAYER == id) {
if (PR_IO_LAYER_HEAD == fd->identity) if (PR_IO_LAYER_HEAD == fd->identity) {
return fd->lower; return fd->lower;
else }
return fd; return fd;
} }
for (layer = fd; layer != NULL; layer = layer->lower) for (layer = fd; layer != NULL; layer = layer->lower)

View file

@ -24,17 +24,16 @@ PR_IMPLEMENT(PRFileMap *) PR_CreateFileMap(
|| prot == PR_PROT_WRITECOPY); || prot == PR_PROT_WRITECOPY);
fmap = PR_NEWZAP(PRFileMap); fmap = PR_NEWZAP(PRFileMap);
if (NULL == fmap) { if (NULL == fmap) {
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
return NULL; return NULL;
} }
fmap->fd = fd; fmap->fd = fd;
fmap->prot = prot; fmap->prot = prot;
if (_PR_MD_CREATE_FILE_MAP(fmap, size) == PR_SUCCESS) { if (_PR_MD_CREATE_FILE_MAP(fmap, size) == PR_SUCCESS) {
return fmap; return fmap;
} else { }
PR_DELETE(fmap); PR_DELETE(fmap);
return NULL; return NULL;
}
} }
PR_IMPLEMENT(PRInt32) PR_GetMemMapAlignment(void) PR_IMPLEMENT(PRInt32) PR_GetMemMapAlignment(void)

View file

@ -409,7 +409,8 @@ Convert(ScanfState *state, const char *fmt)
ch = GET(state); ch = GET(state);
if (ch == EOF) { if (ch == EOF) {
return NULL; return NULL;
} else if (state->assign) { }
if (state->assign) {
*cArg++ = ch; *cArg++ = ch;
} }
} }
@ -602,10 +603,9 @@ StringGetChar(void *stream)
if (*cPtr == '\0') { if (*cPtr == '\0') {
return EOF; return EOF;
} else {
*((char **) stream) = cPtr + 1;
return (unsigned char) *cPtr;
} }
*((char **) stream) = cPtr + 1;
return (unsigned char) *cPtr;
} }
static void static void

View file

@ -7,6 +7,12 @@
#include <string.h> #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. */ /* These two functions are only used in assertions. */
@ -304,6 +310,48 @@ static PRStatus PR_CALLBACK SocketConnectContinue(
} }
PR_ASSERT(out_flags & PR_POLL_WRITE); 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; return PR_SUCCESS;
#elif defined(XP_OS2) #elif defined(XP_OS2)
@ -751,7 +799,7 @@ static PRInt32 PR_CALLBACK SocketSendTo(
#endif #endif
count = 0; count = 0;
while (amount > 0) { do {
temp = _PR_MD_SENDTO(fd, buf, amount, flags, temp = _PR_MD_SENDTO(fd, buf, amount, flags,
addrp, PR_NETADDR_SIZE(addr), timeout); addrp, PR_NETADDR_SIZE(addr), timeout);
if (temp < 0) { if (temp < 0) {
@ -764,10 +812,60 @@ static PRInt32 PR_CALLBACK SocketSendTo(
} }
buf = (const void*) ((const char*)buf + temp); buf = (const void*) ((const char*)buf + temp);
amount -= temp; amount -= temp;
} } while (amount > 0);
return count; 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, static PRInt32 PR_CALLBACK SocketRecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,
PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout) PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
{ {
@ -1066,6 +1164,15 @@ static PRInt16 PR_CALLBACK SocketPoll(
PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
{ {
*out_flags = 0; *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; return in_flags;
} /* SocketPoll */ } /* SocketPoll */
@ -1090,7 +1197,11 @@ static PRIOMethods tcpMethods = {
SocketRecv, SocketRecv,
SocketSend, SocketSend,
(PRRecvfromFN)_PR_InvalidInt, (PRRecvfromFN)_PR_InvalidInt,
#if defined(_WIN64) && defined(WIN95)
SocketTCPSendTo, /* This is for fast open. We imitate Linux interface. */
#else
(PRSendtoFN)_PR_InvalidInt, (PRSendtoFN)_PR_InvalidInt,
#endif
SocketPoll, SocketPoll,
SocketAcceptRead, SocketAcceptRead,
SocketTransmitFile, SocketTransmitFile,

View file

@ -3316,11 +3316,11 @@ int _MD_unix_get_nonblocking_connect_error(int osfd)
return errno; return errno;
} else { } else {
return err; return err;
} }
} }
} else { } else {
return ECONNREFUSED; return ECONNREFUSED;
} }
#elif defined(UNIXWARE) #elif defined(UNIXWARE)
/* /*
* getsockopt() fails with EPIPE, so use getmsg() instead. * 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); rv = getmsg(osfd, NULL, NULL, &flags);
PR_ASSERT(-1 == rv || 0 == rv); PR_ASSERT(-1 == rv || 0 == rv);
if (-1 == rv && errno != EAGAIN && errno != EWOULDBLOCK) { if (-1 == rv && errno != EAGAIN && errno != EWOULDBLOCK) {
return errno; return errno;
} }
return 0; /* no error */ return 0; /* no error */
#else #else
int err; int err;
_PRSockLen_t optlen = sizeof(err); _PRSockLen_t optlen = sizeof(err);
if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen) == -1) { if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char*)&err, &optlen) == -1) {
return errno; return errno;
} else { }
return err; return err;
}
#endif #endif
} }

View file

@ -247,13 +247,14 @@ ForkAndExec(
PR_DELETE(newEnvp); PR_DELETE(newEnvp);
} }
return NULL; return NULL;
} else if (0 == process->md.pid) { /* the child process */ }
/* 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 * If the child process needs to exit, it must call _exit().
* the standard I/O file descriptors, and hence corrupt * Do not call exit(), because exit() will flush and close
* the parent process's standard I/O data structures. * the standard I/O file descriptors, and hence corrupt
*/ * the parent process's standard I/O data structures.
*/
#if !defined(NTO) && !defined(SYMBIAN) #if !defined(NTO) && !defined(SYMBIAN)
if (attr) { if (attr) {
@ -498,10 +499,9 @@ ExtractExitStatus(int rawExitStatus)
#endif #endif
if (WIFEXITED(rawExitStatus)) { if (WIFEXITED(rawExitStatus)) {
return WEXITSTATUS(rawExitStatus); return WEXITSTATUS(rawExitStatus);
} else { }
PR_ASSERT(WIFSIGNALED(rawExitStatus)); PR_ASSERT(WIFSIGNALED(rawExitStatus));
return _PR_SIGNALED_EXITSTATUS; return _PR_SIGNALED_EXITSTATUS;
}
} }
static void static void
@ -624,8 +624,8 @@ static void WaitPidDaemonThread(void *unused)
} while (sizeof(buf) == rv || (-1 == rv && EINTR == errno)); } while (sizeof(buf) == rv || (-1 == rv && EINTR == errno));
#ifdef _PR_SHARE_CLONES #ifdef _PR_SHARE_CLONES
PR_Unlock(pr_wp.ml);
while ((op = pr_wp.opHead) != NULL) { while ((op = pr_wp.opHead) != NULL) {
PR_Unlock(pr_wp.ml);
op->process = ForkAndExec(op->path, op->argv, op->process = ForkAndExec(op->path, op->argv,
op->envp, op->attr); op->envp, op->attr);
if (NULL == op->process) { if (NULL == op->process) {
@ -639,8 +639,8 @@ static void WaitPidDaemonThread(void *unused)
} }
op->done = PR_TRUE; op->done = PR_TRUE;
PR_NotifyCondVar(op->doneCV); PR_NotifyCondVar(op->doneCV);
PR_Unlock(pr_wp.ml);
} }
PR_Unlock(pr_wp.ml);
#endif #endif
while (1) { while (1) {

View file

@ -76,8 +76,8 @@ extern PRSharedMemory * _MD_OpenSharedMemory(
/* copy args to struct */ /* copy args to struct */
strcpy( shm->ipcname, ipcname ); strcpy( shm->ipcname, ipcname );
shm->size = size; shm->size = size;
shm->mode = mode; shm->mode = mode;
shm->flags = flags; shm->flags = flags;
shm->ident = _PR_SHM_IDENT; shm->ident = _PR_SHM_IDENT;
@ -500,30 +500,32 @@ extern PRFileMap* _md_OpenAnonFileMap(
("_md_OpenAnonFileMap(): PR_snprintf(): failed, generating filename")); ("_md_OpenAnonFileMap(): PR_snprintf(): failed, generating filename"));
goto Finished; goto Finished;
} }
/* create the file */ /* create the file */
osfd = open( genName, (O_CREAT | O_EXCL | O_RDWR), mode ); osfd = open(genName, (O_CREAT | O_EXCL | O_RDWR), mode);
if ( -1 == osfd ) { if (-1 == osfd) {
if ( EEXIST == errno ) { if (EEXIST == errno) {
PR_smprintf_free( genName ); PR_smprintf_free(genName);
continue; /* name exists, try again */ continue; /* name exists, try again */
} else { }
_PR_MD_MAP_OPEN_ERROR( errno ); _PR_MD_MAP_OPEN_ERROR(errno);
PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, PR_LOG(
("_md_OpenAnonFileMap(): open(): failed, filename: %s, errno: %d", _pr_shma_lm,
genName, PR_GetOSError())); PR_LOG_DEBUG,
PR_smprintf_free( genName ); ("_md_OpenAnonFileMap(): open(): failed, filename: %s, errno: %d",
goto Finished; genName,
} PR_GetOSError()));
PR_smprintf_free(genName);
goto Finished;
} }
break; /* name generation and open successful, break; */ break; /* name generation and open successful, break; */
} /* end for() */ } /* end for() */
if ( incr == maxTries ) { if (incr == maxTries) {
PR_ASSERT( -1 == osfd ); PR_ASSERT(-1 == osfd);
PR_ASSERT( EEXIST == errno ); PR_ASSERT(EEXIST == errno);
_PR_MD_MAP_OPEN_ERROR( errno ); _PR_MD_MAP_OPEN_ERROR(errno);
goto Finished; goto Finished;
} }
urc = unlink( genName ); urc = unlink( genName );

View file

@ -155,7 +155,7 @@ PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
pd->out_flags = 0; /* pre-condition */ pd->out_flags = 0; /* pre-condition */
/* make sure this is an NSPR supported stack */ /* make sure this is an NSPR supported stack */
bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); 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) if ((NULL != bottom)
&& (_PR_FILEDESC_OPEN == bottom->secret->state)) && (_PR_FILEDESC_OPEN == bottom->secret->state))

View file

@ -294,8 +294,7 @@ _PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
PRInt32 rv, err; PRInt32 rv, err;
PRInt32 bytesSent = 0; PRInt32 bytesSent = 0;
while(bytesSent < amount) do {
{
while ((rv = sendto( osfd, buf, amount, 0, (struct sockaddr *) addr, while ((rv = sendto( osfd, buf, amount, 0, (struct sockaddr *) addr,
addrlen)) == -1) addrlen)) == -1)
{ {
@ -327,10 +326,177 @@ _PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
return -1; return -1;
} }
} }
} } while(bytesSent < amount);
return bytesSent; 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 PRInt32
_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, _PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout) PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)

View file

@ -177,19 +177,21 @@ pr_inet_aton(const char *cp, PRUint32 *addr)
case 2: /*%< a.b -- 8.24 bits */ case 2: /*%< a.b -- 8.24 bits */
if (val > 0xffffffU) if (val > 0xffffffU)
return (0); return (0);
val |= parts[0] << 24; val |= (unsigned int)parts[0] << 24;
break; break;
case 3: /*%< a.b.c -- 8.8.16 bits */ case 3: /*%< a.b.c -- 8.8.16 bits */
if (val > 0xffffU) if (val > 0xffffU)
return (0); return (0);
val |= (parts[0] << 24) | (parts[1] << 16); val |= ((unsigned int)parts[0] << 24) | ((unsigned int)parts[1] << 16);
break; break;
case 4: /*%< a.b.c.d -- 8.8.8.8 bits */ case 4: /*%< a.b.c.d -- 8.8.8.8 bits */
if (val > 0xffU) if (val > 0xffU)
return (0); 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; break;
} }
*addr = PR_htonl(val); *addr = PR_htonl(val);

View file

@ -1405,7 +1405,7 @@ PR_IMPLEMENT(PRStatus) PR_InitializeNetAddr(
PRStatus rv = PR_SUCCESS; PRStatus rv = PR_SUCCESS;
if (!_pr_initialized) _PR_ImplicitInitialization(); 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.family = AF_INET;
addr->inet.port = htons(port); addr->inet.port = htons(port);
switch (val) switch (val)
@ -1483,18 +1483,20 @@ PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val)
if (val == PR_IpAddrAny) { if (val == PR_IpAddrAny) {
if (_PR_IN6_IS_ADDR_UNSPECIFIED((PRIPv6Addr *)&addr->ipv6.ip)) { if (_PR_IN6_IS_ADDR_UNSPECIFIED((PRIPv6Addr *)&addr->ipv6.ip)) {
return PR_TRUE; return PR_TRUE;
} else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip) }
&& _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip) if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
== htonl(INADDR_ANY)) { && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
return PR_TRUE; == htonl(INADDR_ANY)) {
return PR_TRUE;
} }
} else if (val == PR_IpAddrLoopback) { } else if (val == PR_IpAddrLoopback) {
if (_PR_IN6_IS_ADDR_LOOPBACK((PRIPv6Addr *)&addr->ipv6.ip)) { if (_PR_IN6_IS_ADDR_LOOPBACK((PRIPv6Addr *)&addr->ipv6.ip)) {
return PR_TRUE; return PR_TRUE;
} else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip) }
&& _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip) if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
== htonl(INADDR_LOOPBACK)) { && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
return PR_TRUE; == htonl(INADDR_LOOPBACK)) {
return PR_TRUE;
} }
} else if (val == PR_IpAddrV4Mapped } else if (val == PR_IpAddrV4Mapped
&& _PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)) { && _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 (addr->raw.family == AF_INET) {
if (val == PR_IpAddrAny && addr->inet.ip == htonl(INADDR_ANY)) { if (val == PR_IpAddrAny && addr->inet.ip == htonl(INADDR_ANY)) {
return PR_TRUE; 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; return PR_TRUE;
} }
} }
@ -1777,18 +1780,12 @@ PR_IMPLEMENT(PRUint64) PR_ntohll(PRUint64 n)
#ifdef IS_BIG_ENDIAN #ifdef IS_BIG_ENDIAN
return n; return n;
#else #else
PRUint64 tmp;
PRUint32 hi, lo; PRUint32 hi, lo;
LL_L2UI(lo, n); lo = (PRUint32)n;
LL_SHR(tmp, n, 32); hi = (PRUint32)(n >> 32);
LL_L2UI(hi, tmp);
hi = PR_ntohl(hi); hi = PR_ntohl(hi);
lo = PR_ntohl(lo); lo = PR_ntohl(lo);
LL_UI2L(n, lo); return ((PRUint64)lo << 32) + (PRUint64)hi;
LL_SHL(n, n, 32);
LL_UI2L(tmp, hi);
LL_ADD(n, n, tmp);
return n;
#endif #endif
} /* ntohll */ } /* ntohll */
@ -1797,18 +1794,12 @@ PR_IMPLEMENT(PRUint64) PR_htonll(PRUint64 n)
#ifdef IS_BIG_ENDIAN #ifdef IS_BIG_ENDIAN
return n; return n;
#else #else
PRUint64 tmp;
PRUint32 hi, lo; PRUint32 hi, lo;
LL_L2UI(lo, n); lo = (PRUint32)n;
LL_SHR(tmp, n, 32); hi = (PRUint32)(n >> 32);
LL_L2UI(hi, tmp);
hi = htonl(hi); hi = htonl(hi);
lo = htonl(lo); lo = htonl(lo);
LL_UI2L(n, lo); return ((PRUint64)lo << 32) + (PRUint64)hi;
LL_SHL(n, n, 32);
LL_UI2L(tmp, hi);
LL_ADD(n, n, tmp);
return n;
#endif #endif
} /* htonll */ } /* htonll */

View file

@ -279,8 +279,7 @@ static int IsLeapYear(PRInt16 year)
{ {
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
return 1; return 1;
else return 0;
return 0;
} }
/* /*
@ -495,6 +494,20 @@ PR_NormalizeTime(PRExplodedTime *time, PRTimeParamFn params)
#define MT_safe_localtime localtime_r #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 #else
#define HAVE_LOCALTIME_MONITOR 1 /* We use 'monitor' to serialize our calls #define HAVE_LOCALTIME_MONITOR 1 /* We use 'monitor' to serialize our calls
@ -580,6 +593,7 @@ PR_LocalTimeParameters(const PRExplodedTime *gmt)
PRTimeParameters retVal; PRTimeParameters retVal;
struct tm localTime; struct tm localTime;
struct tm *localTimeResult;
time_t secs; time_t secs;
PRTime secs64; PRTime secs64;
PRInt64 usecPerSec; PRInt64 usecPerSec;
@ -606,7 +620,12 @@ PR_LocalTimeParameters(const PRExplodedTime *gmt)
*/ */
secs = 86400L; 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. */ /* GMT is 00:00:00, 2nd of Jan. */
@ -957,6 +976,7 @@ PR_ParseTimeStringToExplodedTime(
int hour = -1; int hour = -1;
int min = -1; int min = -1;
int sec = -1; int sec = -1;
struct tm *localTimeResult;
const char *rest = string; const char *rest = string;
@ -1215,7 +1235,7 @@ PR_ParseTimeStringToExplodedTime(
if ((end - rest) > 2) if ((end - rest) > 2)
/* it is [0-9][0-9][0-9]+: */ /* it is [0-9][0-9][0-9]+: */
break; break;
else if ((end - rest) == 2) if ((end - rest) == 2)
tmp_hour = ((rest[0]-'0')*10 + tmp_hour = ((rest[0]-'0')*10 +
(rest[1]-'0')); (rest[1]-'0'));
else else
@ -1230,12 +1250,12 @@ PR_ParseTimeStringToExplodedTime(
if (end == rest) if (end == rest)
/* no digits after first colon? */ /* no digits after first colon? */
break; break;
else if ((end - rest) > 2) if ((end - rest) > 2)
/* it is [0-9][0-9][0-9]+: */ /* it is [0-9][0-9][0-9]+: */
break; break;
else if ((end - rest) == 2) if ((end - rest) == 2)
tmp_min = ((rest[0]-'0')*10 + tmp_min = ((rest[0]-'0')*10 +
(rest[1]-'0')); (rest[1]-'0'));
else else
tmp_min = (rest[0]-'0'); tmp_min = (rest[0]-'0');
@ -1253,7 +1273,7 @@ PR_ParseTimeStringToExplodedTime(
else if ((end - rest) > 2) else if ((end - rest) > 2)
/* it is [0-9][0-9][0-9]+: */ /* it is [0-9][0-9][0-9]+: */
break; break;
else if ((end - rest) == 2) if ((end - rest) == 2)
tmp_sec = ((rest[0]-'0')*10 + tmp_sec = ((rest[0]-'0')*10 +
(rest[1]-'0')); (rest[1]-'0'));
else else
@ -1287,7 +1307,7 @@ PR_ParseTimeStringToExplodedTime(
rest = end; rest = end;
break; break;
} }
else if ((*end == '/' || *end == '-') && if ((*end == '/' || *end == '-') &&
end[1] >= '0' && end[1] <= '9') end[1] >= '0' && end[1] <= '9')
{ {
/* Perhaps this is 6/16/95, 16/6/95, 6-16-95, or 16-6-95 /* 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 zone_offset for the date we are parsing is the same as
the zone offset on 00:00:00 2 Jan 1970 GMT. */ the zone offset on 00:00:00 2 Jan 1970 GMT. */
secs = 86400; 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 zone_offset = localTime.tm_min
+ 60 * localTime.tm_hour + 60 * localTime.tm_hour
+ 1440 * (localTime.tm_mday - 2); + 1440 * (localTime.tm_mday - 2);
@ -1989,24 +2013,22 @@ pr_WeekOfYear(const PRExplodedTime* time, unsigned int firstDayOfWeek)
dayOfWeek = time->tm_wday - firstDayOfWeek; dayOfWeek = time->tm_wday - firstDayOfWeek;
if (dayOfWeek < 0) if (dayOfWeek < 0)
dayOfWeek += 7; dayOfWeek += 7;
dayOfYear = time->tm_yday - dayOfWeek;
dayOfYear = time->tm_yday - dayOfWeek;
if( dayOfYear <= 0 ) if( dayOfYear <= 0 )
{ {
/* If dayOfYear is <= 0, it is in the first partial week of the year. */ /* If dayOfYear is <= 0, it is in the first partial week of the year. */
return 0; return 0;
} }
else
{ /* Count the number of full weeks ( dayOfYear / 7 ) then add a week if there
/* 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
* 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
* 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"
* actual day representing the given time, any days in week 0 will be "absorbed" * as extra days in the given week.
* as extra days in the given week. */
*/ return (dayOfYear / 7) + ( (dayOfYear % 7) == 0 ? 0 : 1 );
return (dayOfYear / 7) + ( (dayOfYear % 7) == 0 ? 0 : 1 );
}
} }

View file

@ -862,16 +862,16 @@ PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod,
if ((rv == PR_FAILURE) && ((err = PR_GetError()) == PR_IN_PROGRESS_ERROR)){ if ((rv == PR_FAILURE) && ((err = PR_GetError()) == PR_IN_PROGRESS_ERROR)){
/* connection pending */ /* connection pending */
return(queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_CONNECT)); 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 */ /* queue a job, when a timer expires */

View file

@ -74,6 +74,10 @@ static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING
#endif /* XP_UNIX */ #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) PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint(void)
{ {
#ifdef XP_UNIX #ifdef XP_UNIX
@ -88,6 +92,9 @@ PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint(void)
#endif #endif
return &VERSION_DESC_NAME; return &VERSION_DESC_NAME;
} /* versionEntryPointType */ } /* versionEntryPointType */
#ifdef _PR_HAS_PRAGMA_DIAGNOSTIC
#pragma GCC diagnostic pop
#endif
/* prvrsion.c */ /* prvrsion.c */

View file

@ -164,6 +164,9 @@ static ssize_t (*pt_aix_sendfile_fptr)() = NULL;
#ifndef TCP_CORK #ifndef TCP_CORK
#define TCP_CORK 3 #define TCP_CORK 3
#endif #endif
#ifndef MSG_FASTOPEN
#define MSG_FASTOPEN 0x20000000
#endif
#endif #endif
#ifdef _PR_IPV6_V6ONLY_PROBE #ifdef _PR_IPV6_V6ONLY_PROBE
@ -821,7 +824,7 @@ retry:
op->arg3.amount -= bytes; /* and reduce the required count */ op->arg3.amount -= bytes; /* and reduce the required count */
return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE; 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; op->result.code = -1;
return PR_TRUE; 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 */ op->arg3.amount -= bytes; /* and reduce the required count */
return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE; 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; op->result.code = -1;
return PR_TRUE; 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 */ op->arg3.amount -= iov_index; /* and array length */
return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE; 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; op->result.code = -1;
return PR_TRUE; 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 */ op->arg3.amount -= bytes; /* and reduce the required count */
return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE; 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; op->result.code = -1;
return PR_TRUE; return PR_TRUE;
@ -1542,23 +1545,26 @@ static PRStatus pt_Connect(
pt_SockLen addr_len; pt_SockLen addr_len;
const PRNetAddr *addrp = addr; const PRNetAddr *addrp = addr;
#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6) #if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)
PRUint16 md_af = addr->raw.family;
PRNetAddr addrCopy; PRNetAddr addrCopy;
#endif #endif
#ifdef _PR_HAVE_SOCKADDR_LEN
PRUint16 md_af = addr->raw.family;
#endif
if (pt_TestAbort()) return PR_FAILURE; if (pt_TestAbort()) return PR_FAILURE;
PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
addr_len = PR_NETADDR_SIZE(addr); addr_len = PR_NETADDR_SIZE(addr);
#if defined(_PR_INET6) #ifdef _PR_INET6
if (addr->raw.family == PR_AF_INET6) { if (addr->raw.family == PR_AF_INET6) {
md_af = AF_INET6; #ifdef _PR_HAVE_SOCKADDR_LEN
#ifndef _PR_HAVE_SOCKADDR_LEN md_af = AF_INET6;
addrCopy = *addr; #else
addrCopy.raw.family = AF_INET6; addrCopy = *addr;
addrp = &addrCopy; addrCopy.raw.family = AF_INET6;
addrp = &addrCopy;
#endif #endif
} }
#endif #endif
#ifdef _PR_HAVE_SOCKADDR_LEN #ifdef _PR_HAVE_SOCKADDR_LEN
@ -1732,9 +1738,11 @@ static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *addr)
pt_SockLen addr_len; pt_SockLen addr_len;
const PRNetAddr *addrp = addr; const PRNetAddr *addrp = addr;
#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6) #if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)
PRUint16 md_af = addr->raw.family;
PRNetAddr addrCopy; PRNetAddr addrCopy;
#endif #endif
#ifdef _PR_HAVE_SOCKADDR_LEN
PRUint16 md_af = addr->raw.family;
#endif
if (pt_TestAbort()) return PR_FAILURE; if (pt_TestAbort()) return PR_FAILURE;
@ -1749,15 +1757,16 @@ static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *addr)
} }
} }
#if defined(_PR_INET6) #ifdef _PR_INET6
if (addr->raw.family == PR_AF_INET6) { if (addr->raw.family == PR_AF_INET6) {
md_af = AF_INET6; #ifdef _PR_HAVE_SOCKADDR_LEN
#ifndef _PR_HAVE_SOCKADDR_LEN md_af = AF_INET6;
addrCopy = *addr; #else
addrCopy.raw.family = AF_INET6; addrCopy = *addr;
addrp = &addrCopy; addrCopy.raw.family = AF_INET6;
addrp = &addrCopy;
#endif #endif
} }
#endif #endif
addr_len = PR_NETADDR_SIZE(addr); addr_len = PR_NETADDR_SIZE(addr);
@ -1989,22 +1998,25 @@ static PRInt32 pt_SendTo(
pt_SockLen addr_len; pt_SockLen addr_len;
const PRNetAddr *addrp = addr; const PRNetAddr *addrp = addr;
#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6) #if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)
PRUint16 md_af = addr->raw.family;
PRNetAddr addrCopy; PRNetAddr addrCopy;
#endif #endif
#ifdef _PR_HAVE_SOCKADDR_LEN
PRUint16 md_af = addr->raw.family;
#endif
if (pt_TestAbort()) return bytes; if (pt_TestAbort()) return bytes;
PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
#if defined(_PR_INET6) #ifdef _PR_INET6
if (addr->raw.family == PR_AF_INET6) { if (addr->raw.family == PR_AF_INET6) {
md_af = AF_INET6; #ifdef _PR_HAVE_SOCKADDR_LEN
#ifndef _PR_HAVE_SOCKADDR_LEN md_af = AF_INET6;
addrCopy = *addr; #else
addrCopy.raw.family = AF_INET6; addrCopy = *addr;
addrp = &addrCopy; addrCopy.raw.family = AF_INET6;
addrp = &addrCopy;
#endif #endif
} }
#endif #endif
addr_len = PR_NETADDR_SIZE(addr); addr_len = PR_NETADDR_SIZE(addr);
@ -2044,6 +2056,101 @@ static PRInt32 pt_SendTo(
return bytes; return bytes;
} /* pt_SendTo */ } /* 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, static PRInt32 pt_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,
PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout) PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
{ {
@ -2767,22 +2874,21 @@ static PRStatus pt_GetSockName(PRFileDesc *fd, PRNetAddr *addr)
if (rv == -1) { if (rv == -1) {
pt_MapError(_PR_MD_MAP_GETSOCKNAME_ERROR, errno); pt_MapError(_PR_MD_MAP_GETSOCKNAME_ERROR, errno);
return PR_FAILURE; return PR_FAILURE;
} else { }
#ifdef _PR_HAVE_SOCKADDR_LEN #ifdef _PR_HAVE_SOCKADDR_LEN
/* ignore the sa_len field of struct sockaddr */ /* ignore the sa_len field of struct sockaddr */
if (addr) if (addr)
{ {
addr->raw.family = ((struct sockaddr*)addr)->sa_family; addr->raw.family = ((struct sockaddr*)addr)->sa_family;
} }
#endif /* _PR_HAVE_SOCKADDR_LEN */ #endif /* _PR_HAVE_SOCKADDR_LEN */
#ifdef _PR_INET6 #ifdef _PR_INET6
if (AF_INET6 == addr->raw.family) if (AF_INET6 == addr->raw.family)
addr->raw.family = PR_AF_INET6; addr->raw.family = PR_AF_INET6;
#endif #endif
PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE); PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
return PR_SUCCESS; return PR_SUCCESS;
}
} /* pt_GetSockName */ } /* pt_GetSockName */
static PRStatus pt_GetPeerName(PRFileDesc *fd, PRNetAddr *addr) static PRStatus pt_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
@ -2798,22 +2904,21 @@ static PRStatus pt_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
if (rv == -1) { if (rv == -1) {
pt_MapError(_PR_MD_MAP_GETPEERNAME_ERROR, errno); pt_MapError(_PR_MD_MAP_GETPEERNAME_ERROR, errno);
return PR_FAILURE; return PR_FAILURE;
} else { }
#ifdef _PR_HAVE_SOCKADDR_LEN #ifdef _PR_HAVE_SOCKADDR_LEN
/* ignore the sa_len field of struct sockaddr */ /* ignore the sa_len field of struct sockaddr */
if (addr) if (addr)
{ {
addr->raw.family = ((struct sockaddr*)addr)->sa_family; addr->raw.family = ((struct sockaddr*)addr)->sa_family;
} }
#endif /* _PR_HAVE_SOCKADDR_LEN */ #endif /* _PR_HAVE_SOCKADDR_LEN */
#ifdef _PR_INET6 #ifdef _PR_INET6
if (AF_INET6 == addr->raw.family) if (AF_INET6 == addr->raw.family)
addr->raw.family = PR_AF_INET6; addr->raw.family = PR_AF_INET6;
#endif #endif
PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE); PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
return PR_SUCCESS; return PR_SUCCESS;
}
} /* pt_GetPeerName */ } /* pt_GetPeerName */
static PRStatus pt_GetSocketOption(PRFileDesc *fd, PRSocketOptionData *data) static PRStatus pt_GetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
@ -3155,7 +3260,11 @@ static PRIOMethods _pr_tcp_methods = {
pt_Recv, pt_Recv,
pt_Send, pt_Send,
(PRRecvfromFN)_PR_InvalidInt, (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, (PRSendtoFN)_PR_InvalidInt,
#endif
pt_Poll, pt_Poll,
pt_AcceptRead, pt_AcceptRead,
pt_TransmitFile, pt_TransmitFile,
@ -3602,8 +3711,8 @@ PR_IMPLEMENT(PRStatus) PR_Delete(const char *name)
if (rv == -1) { if (rv == -1) {
pt_MapError(_PR_MD_MAP_UNLINK_ERROR, errno); pt_MapError(_PR_MD_MAP_UNLINK_ERROR, errno);
return PR_FAILURE; return PR_FAILURE;
} else }
return PR_SUCCESS; return PR_SUCCESS;
} /* PR_Delete */ } /* PR_Delete */
PR_IMPLEMENT(PRStatus) PR_Access(const char *name, PRAccessHow how) 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); rv = rmdir(name);
if (0 == rv) { if (0 == rv) {
return PR_SUCCESS; return PR_SUCCESS;
} else { }
pt_MapError(_PR_MD_MAP_RMDIR_ERROR, errno); pt_MapError(_PR_MD_MAP_RMDIR_ERROR, errno);
return PR_FAILURE; return PR_FAILURE;
}
} /* PR_Rmdir */ } /* PR_Rmdir */
@ -3847,7 +3955,8 @@ static PRInt32 _pr_poll_with_poll(
/* now locate the NSPR layer at the bottom of the stack */ /* now locate the NSPR layer at the bottom of the stack */
PRFileDesc *bottom = PR_GetIdentitiesLayer( PRFileDesc *bottom = PR_GetIdentitiesLayer(
pds[index].fd, PR_NSPR_IO_LAYER); 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 */ pds[index].out_flags = 0; /* pre-condition */
if ((NULL != bottom) if ((NULL != bottom)
&& (_PR_FILEDESC_OPEN == bottom->secret->state)) && (_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 */ /* now locate the NSPR layer at the bottom of the stack */
PRFileDesc *bottom = PR_GetIdentitiesLayer( PRFileDesc *bottom = PR_GetIdentitiesLayer(
pds[index].fd, PR_NSPR_IO_LAYER); 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 */ pds[index].out_flags = 0; /* pre-condition */
if ((NULL != bottom) if ((NULL != bottom)
&& (_PR_FILEDESC_OPEN == bottom->secret->state)) && (_PR_FILEDESC_OPEN == bottom->secret->state))

View file

@ -55,11 +55,10 @@ void _PR_InitLocks(void)
rv = _PT_PTHREAD_MUTEXATTR_INIT(&_pt_mattr); rv = _PT_PTHREAD_MUTEXATTR_INIT(&_pt_mattr);
PR_ASSERT(0 == rv); PR_ASSERT(0 == rv);
#ifdef LINUX #if (defined(LINUX) && (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) || \
#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) (defined(FREEBSD) && __FreeBSD_version > 700055)
rv = pthread_mutexattr_settype(&_pt_mattr, PTHREAD_MUTEX_ADAPTIVE_NP); rv = pthread_mutexattr_settype(&_pt_mattr, PTHREAD_MUTEX_ADAPTIVE_NP);
PR_ASSERT(0 == rv); PR_ASSERT(0 == rv);
#endif
#endif #endif
rv = _PT_PTHREAD_CONDATTR_INIT(&_pt_cvar_attr); rv = _PT_PTHREAD_CONDATTR_INIT(&_pt_cvar_attr);

View file

@ -143,12 +143,13 @@ ClientThread(void *_action)
if (action != CLIENT_TIMEOUT_SEND) { if (action != CLIENT_TIMEOUT_SEND) {
if ((rv = PR_Send(sock, buf, CLIENT_DATA, if ((rv = PR_Send(sock, buf, CLIENT_DATA,
0, timeoutTime))< 0) { 0, timeoutTime))< 0) {
if (!debug_mode) if (!debug_mode) {
failed_already=1; failed_already=1;
else } else {
PR_fprintf(output, PR_fprintf(output,
"client: unable to send to server (%d, %ld, %ld)\n", "client: unable to send to server (%d, %ld, %ld)\n",
CLIENT_DATA, rv, PR_GetError()); CLIENT_DATA, rv, PR_GetError());
}
goto ErrorExit; goto ErrorExit;
} }
} else { } else {
@ -200,8 +201,9 @@ int i;
continue; continue;
} }
failed_already=1; failed_already=1;
if (debug_mode) if (debug_mode) {
PR_fprintf(output,"accept: ERROR - PR_Bind failed\n"); PR_fprintf(output,"accept: ERROR - PR_Bind failed\n");
}
return; return;
} }

View file

@ -411,15 +411,15 @@ static PRUint32 TimeThis(
PRUint32 overhead, usecs; PRUint32 overhead, usecs;
PRIntervalTime predicted, timein, timeout, ticks; PRIntervalTime predicted, timein, timeout, ticks;
if (debug_mode) if (debug_mode)
printf("Testing %s ...", msg); printf("Testing %s ...", msg);
timein = PR_IntervalNow(); timein = PR_IntervalNow();
predicted = func(loops); predicted = func(loops);
timeout = PR_IntervalNow(); timeout = PR_IntervalNow();
if (debug_mode) if (debug_mode)
printf(" done\n"); printf(" done\n");
ticks = timeout - timein; ticks = timeout - timein;
usecs = PR_IntervalToMicroseconds(ticks); usecs = PR_IntervalToMicroseconds(ticks);
@ -491,17 +491,17 @@ int prmain(int argc, char** argv)
for (cpu = 1; cpu <= cpus; ++cpu) for (cpu = 1; cpu <= cpus; ++cpu)
{ {
if (debug_mode) if (debug_mode)
printf("\nAlarm: Using %d CPU(s)\n", cpu); printf("\nAlarm: Using %d CPU(s)\n", cpu);
PR_SetConcurrency(cpu); PR_SetConcurrency(cpu);
/* some basic time test */ /* some basic time test */
(void)TimeThis("ConditionNotify", ConditionNotify, loops); (void)TimeThis("ConditionNotify", ConditionNotify, loops);
(void)TimeThis("ConditionTimeout", ConditionTimeout, loops); (void)TimeThis("ConditionTimeout", ConditionTimeout, loops);
(void)TimeThis("Alarms1", Alarms1, loops); (void)TimeThis("Alarms1", Alarms1, loops);
(void)TimeThis("Alarms2", Alarms2, loops); (void)TimeThis("Alarms2", Alarms2, loops);
(void)TimeThis("Alarms3", Alarms3, loops); (void)TimeThis("Alarms3", Alarms3, loops);
} }
return 0; return 0;
} }

View file

@ -39,7 +39,7 @@ static char *compatible_version[] = {
"4.9.6", "4.9.6",
"4.10", "4.10.1", "4.10.2", "4.10.3", "4.10.4", "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.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 PR_VERSION
}; };
@ -55,8 +55,8 @@ static char *incompatible_version[] = {
"3.0", "3.0.1", "3.0", "3.0.1",
"3.1", "3.1.1", "3.1.2", "3.1.3", "3.1", "3.1.1", "3.1.2", "3.1.3",
"3.5", "3.5.1", "3.5", "3.5.1",
"4.13.2", "4.16.1",
"4.14", "4.14.1", "4.17", "4.17.1",
"10.0", "11.1", "12.14.20" "10.0", "11.1", "12.14.20"
}; };