diff options
Diffstat (limited to 'pr/src/io')
-rw-r--r-- | pr/src/io/Makefile.in | 8 | ||||
-rw-r--r-- | pr/src/io/prdir.c | 50 | ||||
-rw-r--r-- | pr/src/io/prfdcach.c | 4 | ||||
-rw-r--r-- | pr/src/io/prfile.c | 88 | ||||
-rw-r--r-- | pr/src/io/prio.c | 11 | ||||
-rw-r--r-- | pr/src/io/priometh.c | 12 | ||||
-rw-r--r-- | pr/src/io/pripv6.c | 64 | ||||
-rw-r--r-- | pr/src/io/prlayer.c | 4 | ||||
-rw-r--r-- | pr/src/io/prlog.c | 65 | ||||
-rw-r--r-- | pr/src/io/prmapopt.c | 18 | ||||
-rw-r--r-- | pr/src/io/prmwait.c | 39 | ||||
-rw-r--r-- | pr/src/io/prprf.c | 115 | ||||
-rw-r--r-- | pr/src/io/prsocket.c | 112 | ||||
-rw-r--r-- | pr/src/io/prstdio.c | 38 |
14 files changed, 407 insertions, 221 deletions
diff --git a/pr/src/io/Makefile.in b/pr/src/io/Makefile.in index 179656aa..e7316b38 100644 --- a/pr/src/io/Makefile.in +++ b/pr/src/io/Makefile.in @@ -81,5 +81,13 @@ DEFINES += -D_NSPR_BUILD_ include $(topsrcdir)/config/rules.mk +# An OS/2 Optimization bug causes PR_snprintf() to produce wrong result. +# This suppresses optimization for this single compilation unit. +ifeq ($(MOZ_OS2_TOOLS),VACPP) +$(OBJDIR)/prprf.obj: prprf.c + @$(MAKE_OBJDIR) + $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $< +endif + export:: $(TARGETS) diff --git a/pr/src/io/prdir.c b/pr/src/io/prdir.c index d0f469e9..8aa66435 100644 --- a/pr/src/io/prdir.c +++ b/pr/src/io/prdir.c @@ -18,6 +18,7 @@ * Rights Reserved. * * Contributor(s): + * Roy Yokoyama <yokoyama@netscape.com> * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the @@ -109,3 +110,52 @@ PRInt32 rv; return PR_SUCCESS; } +#ifdef MOZ_UNICODE +/* + * UTF16 Interface + */ +PR_IMPLEMENT(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name) +{ + PRDirUTF16 *dir; + PRStatus sts; + + dir = PR_NEW(PRDirUTF16); + if (dir) { + sts = _PR_MD_OPEN_DIR_UTF16(&dir->md,name); + if (sts != PR_SUCCESS) { + PR_DELETE(dir); + return NULL; + } + } else { + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + } + return dir; +} + +PR_IMPLEMENT(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags) +{ + /* + * _MD_READ_DIR_UTF16 return a PRUnichar* to the name; allocation in + * machine-dependent code + */ + PRUnichar* name = _PR_MD_READ_DIR_UTF16(&dir->md, flags); + dir->d.name = name; + return name ? &dir->d : NULL; +} + +PR_IMPLEMENT(PRStatus) PR_CloseDirUTF16(PRDirUTF16 *dir) +{ + PRInt32 rv; + + if (dir) { + rv = _PR_MD_CLOSE_DIR_UTF16(&dir->md); + PR_DELETE(dir); + if (rv < 0) + return PR_FAILURE; + else + return PR_SUCCESS; + } + return PR_SUCCESS; +} + +#endif /* MOZ_UNICODE */ diff --git a/pr/src/io/prfdcach.c b/pr/src/io/prfdcach.c index 8803a419..82cbf058 100644 --- a/pr/src/io/prfdcach.c +++ b/pr/src/io/prfdcach.c @@ -73,7 +73,7 @@ static PRFileDesc **stack2fd = &(((PRFileDesc*)NULL)->higher); ** Get a FileDescriptor from the cache if one exists. If not allocate ** a new one from the heap. */ -PRFileDesc *_PR_Getfd() +PRFileDesc *_PR_Getfd(void) { PRFileDesc *fd; /* @@ -248,7 +248,7 @@ PR_IMPLEMENT(PRStatus) PR_SetFDCacheSize(PRIntn low, PRIntn high) return PR_SUCCESS; } /* PR_SetFDCacheSize */ -void _PR_InitFdCache() +void _PR_InitFdCache(void) { /* ** The fd caching is enabled by default for DEBUG builds, diff --git a/pr/src/io/prfile.c b/pr/src/io/prfile.c index e19705c7..25354453 100644 --- a/pr/src/io/prfile.c +++ b/pr/src/io/prfile.c @@ -203,7 +203,7 @@ static PRStatus PR_CALLBACK PipeSync(PRFileDesc *fd) return PR_SUCCESS; } -static PRStatus PR_CALLBACK FileInfo(PRFileDesc *fd, PRFileInfo *info) +static PRStatus PR_CALLBACK FileGetInfo(PRFileDesc *fd, PRFileInfo *info) { PRInt32 rv; @@ -214,7 +214,7 @@ static PRStatus PR_CALLBACK FileInfo(PRFileDesc *fd, PRFileInfo *info) return PR_SUCCESS; } -static PRStatus PR_CALLBACK FileInfo64(PRFileDesc *fd, PRFileInfo64 *info) +static PRStatus PR_CALLBACK FileGetInfo64(PRFileDesc *fd, PRFileInfo64 *info) { #ifdef XP_MAC #pragma unused( fd, info ) @@ -276,8 +276,8 @@ static PRIOMethods _pr_fileMethods = { FileSync, FileSeek, FileSeek64, - FileInfo, - FileInfo64, + FileGetInfo, + FileGetInfo64, (PRWritevFN)_PR_InvalidInt, (PRConnectFN)_PR_InvalidStatus, (PRAcceptFN)_PR_InvalidDesc, @@ -422,14 +422,18 @@ PRInt32 PR_GetSysfdTableMax(void) return rlim.rlim_max; #elif defined(AIX) || defined(NEXTSTEP) || defined(QNX) return sysconf(_SC_OPEN_MAX); -#elif defined(WIN32) || defined(OS2) +#elif defined(WIN32) /* * There is a systemwide limit of 65536 user handles. - * Not sure on OS/2, but sounds good. */ return 16384; #elif defined (WIN16) return FOPEN_MAX; +#elif defined(XP_OS2) + ULONG ulReqCount = 0; + ULONG ulCurMaxFH = 0; + DosSetRelMaxFH(&ulReqCount, &ulCurMaxFH); + return ulCurMaxFH; #elif defined (XP_MAC) || defined(XP_BEOS) PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); return -1; @@ -464,9 +468,19 @@ PRInt32 PR_SetSysfdTableSize(int table_size) } return rlim.rlim_cur; +#elif defined(XP_OS2) + PRInt32 tableMax = PR_GetSysfdTableMax(); + if (table_size > tableMax) { + APIRET rc = NO_ERROR; + rc = DosSetMaxFH(table_size); + if (rc == NO_ERROR) + return table_size; + else + return -1; + } + return tableMax; #elif defined(AIX) || defined(NEXTSTEP) || defined(QNX) \ - || defined(WIN32) || defined(WIN16) || defined(OS2) \ - || defined(XP_BEOS) + || defined(WIN32) || defined(WIN16) || defined(XP_BEOS) PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); return -1; #elif defined (XP_MAC) @@ -735,7 +749,7 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe( (*readPipe)->secret->inheritable = _PR_TRI_TRUE; (*writePipe)->secret->inheritable = _PR_TRI_TRUE; return PR_SUCCESS; -#elif defined(XP_UNIX) || defined(XP_OS2) +#elif defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS) #ifdef XP_OS2 HFILE pipefd[2]; #else @@ -765,9 +779,13 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe( close(pipefd[1]); return PR_FAILURE; } - _MD_MakeNonblock(*readPipe); +#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */ + _PR_MD_MAKE_NONBLOCK(*readPipe); +#endif _PR_MD_INIT_FD_INHERITABLE(*readPipe, PR_FALSE); - _MD_MakeNonblock(*writePipe); +#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */ + _PR_MD_MAKE_NONBLOCK(*writePipe); +#endif _PR_MD_INIT_FD_INHERITABLE(*writePipe, PR_FALSE); return PR_SUCCESS; #else @@ -775,3 +793,51 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe( return PR_FAILURE; #endif } + +#ifdef MOZ_UNICODE +/* ================ UTF16 Interfaces ================================ */ +PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16( + const PRUnichar *name, PRIntn flags, PRIntn mode) +{ + PRInt32 osfd; + PRFileDesc *fd = 0; +#if !defined(XP_UNIX) /* BugZilla: 4090 */ + PRBool appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); + + /* Map pr open flags and mode to os specific flags */ + osfd = _PR_MD_OPEN_FILE_UTF16(name, flags, mode); + if (osfd != -1) { + fd = PR_AllocFileDesc(osfd, &_pr_fileMethods); + if (!fd) { + (void) _PR_MD_CLOSE_FILE(osfd); + } else { +#if !defined(XP_UNIX) /* BugZilla: 4090 */ + fd->secret->appendMode = appendMode; +#endif + _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE); + } + } + return fd; +} + +PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info) +{ +#ifdef XP_MAC +#pragma unused (fn, info) +#endif + PRInt32 rv; + + if (!_pr_initialized) _PR_ImplicitInitialization(); + rv = _PR_MD_GETFILEINFO64_UTF16(fn, info); + if (rv < 0) { + return PR_FAILURE; + } else { + return PR_SUCCESS; + } +} + +/* ================ UTF16 Interfaces ================================ */ +#endif /* MOZ_UNICODE */ diff --git a/pr/src/io/prio.c b/pr/src/io/prio.c index 250d9b6f..66ecd7cc 100644 --- a/pr/src/io/prio.c +++ b/pr/src/io/prio.c @@ -164,7 +164,7 @@ PR_IMPLEMENT(PRStatus) PR_SetFDInheritable( PRFileDesc *fd, PRBool inheritable) { -#if defined(XP_UNIX) || defined(WIN32) || defined(XP_OS2) +#if defined(XP_UNIX) || defined(WIN32) || defined(XP_OS2) || defined(XP_BEOS) /* * Only a non-layered, NSPR file descriptor can be inherited * by a child process. @@ -188,3 +188,12 @@ PR_IMPLEMENT(PRStatus) PR_SetFDInheritable( return PR_FAILURE; #endif } + +/* +** This function only has a useful implementation in the debug build of +** the pthreads version. +*/ +PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg) +{ + /* do nothing */ +} /* PT_FPrintStats */ diff --git a/pr/src/io/priometh.c b/pr/src/io/priometh.c index a2b8e9c8..251d46a9 100644 --- a/pr/src/io/priometh.c +++ b/pr/src/io/priometh.c @@ -34,6 +34,8 @@ */ #include "primpl.h" +#include <string.h> + /*****************************************************************************/ /************************** Invalid I/O method object ************************/ /*****************************************************************************/ @@ -76,21 +78,21 @@ PRIOMethods _pr_faulty_methods = { (PRReservedFN)_PR_InvalidInt }; -PRIntn _PR_InvalidInt() +PRIntn _PR_InvalidInt(void) { PR_ASSERT(!"I/O method is invalid"); PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; } /* _PR_InvalidInt */ -PRInt16 _PR_InvalidInt16() +PRInt16 _PR_InvalidInt16(void) { PR_ASSERT(!"I/O method is invalid"); PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; } /* _PR_InvalidInt */ -PRInt64 _PR_InvalidInt64() +PRInt64 _PR_InvalidInt64(void) { PRInt64 rv; LL_I2L(rv, -1); @@ -103,7 +105,7 @@ PRInt64 _PR_InvalidInt64() * An invalid method that returns PRStatus */ -PRStatus _PR_InvalidStatus() +PRStatus _PR_InvalidStatus(void) { PR_ASSERT(!"I/O method is invalid"); PR_SetError(PR_INVALID_METHOD_ERROR, 0); @@ -114,7 +116,7 @@ PRStatus _PR_InvalidStatus() * An invalid method that returns a pointer */ -PRFileDesc *_PR_InvalidDesc() +PRFileDesc *_PR_InvalidDesc(void) { PR_ASSERT(!"I/O method is invalid"); PR_SetError(PR_INVALID_METHOD_ERROR, 0); diff --git a/pr/src/io/pripv6.c b/pr/src/io/pripv6.c index fd104677..a5c2360f 100644 --- a/pr/src/io/pripv6.c +++ b/pr/src/io/pripv6.c @@ -276,51 +276,41 @@ static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketRecvFrom(PRFileDesc *fd, void *buf, #if defined(_PR_INET6_PROBE) PRBool _pr_ipv6_is_present; -PR_EXTERN(PRBool) _pr_test_ipv6_socket(); -#if defined(_PR_HAVE_GETIPNODEBYNAME) -void *_pr_getipnodebyname_fp; -void *_pr_getipnodebyaddr_fp; -void *_pr_freehostent_fp; +extern PRBool _pr_test_ipv6_socket(void); + +#if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) +extern PRStatus _pr_find_getipnodebyname(void); +#endif + +#if !defined(_PR_INET6) && defined(_PR_HAVE_GETADDRINFO) +extern PRStatus _pr_find_getaddrinfo(void); #endif + +static PRBool +_pr_probe_ipv6_presence(void) +{ +#if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) + if (_pr_find_getipnodebyname() != PR_SUCCESS) + return PR_FALSE; #endif +#if !defined(_PR_INET6) && defined(_PR_HAVE_GETADDRINFO) + if (_pr_find_getaddrinfo() != PR_SUCCESS) + return PR_FALSE; +#endif + + return _pr_test_ipv6_socket(); +} +#endif /* _PR_INET6_PROBE */ + PRStatus _pr_init_ipv6() { const PRIOMethods *stubMethods; #if defined(_PR_INET6_PROBE) - -#if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) - PRLibrary *lib; -#if defined(VMS) -#define GETIPNODEBYNAME getenv("GETIPNODEBYNAME") -#define GETIPNODEBYADDR getenv("GETIPNODEBYADDR") -#define FREEHOSTENT getenv("FREEHOSTENT") -#else -#define GETIPNODEBYNAME "getipnodebyname" -#define GETIPNODEBYADDR "getipnodebyaddr" -#define FREEHOSTENT "freehostent" -#endif - _pr_getipnodebyname_fp = PR_FindSymbolAndLibrary(GETIPNODEBYNAME, &lib); - if (NULL != _pr_getipnodebyname_fp) { - _pr_freehostent_fp = PR_FindSymbol(lib, FREEHOSTENT); - if (NULL != _pr_freehostent_fp) { - _pr_getipnodebyaddr_fp = PR_FindSymbol(lib, GETIPNODEBYADDR); - if (NULL != _pr_getipnodebyaddr_fp) - _pr_ipv6_is_present = PR_TRUE; - else - _pr_ipv6_is_present = PR_FALSE; - } else - _pr_ipv6_is_present = PR_FALSE; - (void)PR_UnloadLibrary(lib); - } else - _pr_ipv6_is_present = PR_FALSE; - if (PR_TRUE == _pr_ipv6_is_present) -#endif - - _pr_ipv6_is_present = _pr_test_ipv6_socket(); - if (PR_TRUE == _pr_ipv6_is_present) - return PR_SUCCESS; + _pr_ipv6_is_present = _pr_probe_ipv6_presence(); + if (PR_TRUE == _pr_ipv6_is_present) + return PR_SUCCESS; #endif _pr_ipv6_to_ipv4_id = PR_GetUniqueIdentity("Ipv6_to_Ipv4 layer"); diff --git a/pr/src/io/prlayer.c b/pr/src/io/prlayer.c index d74fa8be..d377f546 100644 --- a/pr/src/io/prlayer.c +++ b/pr/src/io/prlayer.c @@ -459,7 +459,7 @@ static PRIOMethods pl_methods = { (PRReservedFN)_PR_InvalidInt }; -PR_IMPLEMENT(const PRIOMethods*) PR_GetDefaultIOMethods() +PR_IMPLEMENT(const PRIOMethods*) PR_GetDefaultIOMethods(void) { return &pl_methods; } /* PR_GetDefaultIOMethods */ @@ -736,7 +736,7 @@ PR_IMPLEMENT(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd, PRDescIdentity i return NULL; } /* PR_GetIdentitiesLayer */ -void _PR_InitLayerCache() +void _PR_InitLayerCache(void) { memset(&identity_cache, 0, sizeof(identity_cache)); identity_cache.ml = PR_NewLock(); diff --git a/pr/src/io/prlog.c b/pr/src/io/prlog.c index 16f68823..b73543f8 100644 --- a/pr/src/io/prlog.c +++ b/pr/src/io/prlog.c @@ -194,13 +194,16 @@ void _PR_InitLog(void) ev = PR_GetEnv("NSPR_LOG_MODULES"); if (ev && ev[0]) { - char module[64]; + char module[64]; /* Security-Critical: If you change this + * size, you must also change the sscanf + * format string to be size-1. + */ PRBool isSync = PR_FALSE; PRIntn evlen = strlen(ev), pos = 0; PRInt32 bufSize = DEFAULT_BUF_SIZE; while (pos < evlen) { PRIntn level = 1, count = 0, delta = 0; - count = sscanf(&ev[pos], "%64[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789]%n:%d%n", + count = sscanf(&ev[pos], "%63[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789]%n:%d%n", module, &delta, &level, &delta); pos += delta; if (count == 0) break; @@ -232,7 +235,7 @@ void _PR_InitLog(void) /*found:*/ count = sscanf(&ev[pos], " , %n", &delta); pos += delta; - if (count == -1) break; + if (count == EOF) break; } PR_SetLogBuffering(isSync ? bufSize : 0); @@ -266,7 +269,13 @@ void _PR_LogCleanup(void) PR_LogFlush(); #ifdef _PR_USE_STDIO_FOR_LOGGING - if (logFile && logFile != stdout && logFile != stderr) { + if (logFile + && logFile != stdout + && logFile != stderr +#ifdef XP_PC + && logFile != WIN32_DEBUG_FILE +#endif + ) { fclose(logFile); } #else @@ -277,11 +286,16 @@ void _PR_LogCleanup(void) while (lm != NULL) { PRLogModuleInfo *next = lm->next; - PR_Free((/*const*/ char *)lm->name); + free((/*const*/ char *)lm->name); PR_Free(lm); lm = next; } logModules = NULL; + + if (_pr_logLock) { + PR_DestroyLock(_pr_logLock); + _pr_logLock = NULL; + } } static void _PR_SetLogModuleLevel( PRLogModuleInfo *lm ) @@ -290,12 +304,15 @@ static void _PR_SetLogModuleLevel( PRLogModuleInfo *lm ) ev = PR_GetEnv("NSPR_LOG_MODULES"); if (ev && ev[0]) { - char module[64]; + char module[64]; /* Security-Critical: If you change this + * size, you must also change the sscanf + * format string to be size-1. + */ PRIntn evlen = strlen(ev), pos = 0; while (pos < evlen) { PRIntn level = 1, count = 0, delta = 0; - count = sscanf(&ev[pos], "%64[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789]%n:%d%n", + count = sscanf(&ev[pos], "%63[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789]%n:%d%n", module, &delta, &level, &delta); pos += delta; if (count == 0) break; @@ -314,7 +331,7 @@ static void _PR_SetLogModuleLevel( PRLogModuleInfo *lm ) } count = sscanf(&ev[pos], " , %n", &delta); pos += delta; - if (count == -1) break; + if (count == EOF) break; } } } /* end _PR_SetLogModuleLevel() */ @@ -344,24 +361,33 @@ PR_IMPLEMENT(PRBool) PR_SetLogFile(const char *file) #ifdef XP_PC if ( strcmp( file, "WinDebug") == 0) { - logFile = WIN32_DEBUG_FILE; - return(PR_TRUE); + newLogFile = WIN32_DEBUG_FILE; } + else #endif - newLogFile = fopen(file, "w"); - if (newLogFile) { + { + newLogFile = fopen(file, "w"); + if (!newLogFile) + return PR_FALSE; + /* We do buffering ourselves. */ setvbuf(newLogFile, NULL, _IONBF, 0); - if (logFile && logFile != stdout && logFile != stderr) { - fclose(logFile); - } - logFile = newLogFile; } - return (PRBool) (newLogFile != 0); + if (logFile + && logFile != stdout + && logFile != stderr +#ifdef XP_PC + && logFile != WIN32_DEBUG_FILE +#endif + ) { + fclose(logFile); + } + logFile = newLogFile; + return PR_TRUE; #else PRFileDesc *newLogFile; - newLogFile = PR_Open(file, PR_WRONLY|PR_CREATE_FILE, 0666); + newLogFile = PR_Open(file, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE, 0666); if (newLogFile) { if (logFile && logFile != _pr_stdout && logFile != _pr_stderr) { PR_Close(logFile); @@ -482,8 +508,7 @@ PR_IMPLEMENT(void) PR_Abort(void) #include <builtin.h> static void DebugBreak(void) { _interrupt(3); } #elif defined(XP_OS2_EMX) -/* Force a trap */ -static void DebugBreak(void) { int *pTrap=NULL; *pTrap = 1; } +static void DebugBreak(void) { asm("int $3"); } #else static void DebugBreak(void) { } #endif diff --git a/pr/src/io/prmapopt.c b/pr/src/io/prmapopt.c index f017c36a..2e6d219a 100644 --- a/pr/src/io/prmapopt.c +++ b/pr/src/io/prmapopt.c @@ -46,10 +46,20 @@ * includes winsock.h, with _WIN32_WINNT undefined. */ -#ifdef WINNT +#if defined(WINNT) || defined(__MINGW32__) #include <winsock.h> #endif +/* MinGW doesn't define these in its winsock.h. */ +#ifdef __MINGW32__ +#ifndef IP_TTL +#define IP_TTL 7 +#endif +#ifndef IP_TOS +#define IP_TOS 8 +#endif +#endif + #include "primpl.h" #if defined(NEXTSTEP) @@ -57,7 +67,7 @@ #include <netinet/in_systm.h> /* n_short, n_long, n_time */ #endif -#if defined(XP_UNIX) || defined(OS2) +#if defined(XP_UNIX) || defined(OS2) || (defined(XP_BEOS) && defined(BONE_VERSION)) #include <netinet/tcp.h> /* TCP_NODELAY, TCP_MAXSEG */ #endif @@ -86,7 +96,7 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat { case PR_SockOpt_Linger: { -#if !defined(XP_BEOS) +#if !defined(XP_BEOS) || defined(BONE_VERSION) struct linger linger; length = sizeof(linger); rv = _PR_MD_GETSOCKOPT( @@ -244,7 +254,7 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt { case PR_SockOpt_Linger: { -#if !defined(XP_BEOS) +#if !defined(XP_BEOS) || defined(BONE_VERSION) struct linger linger; linger.l_onoff = data->value.linger.polarity; linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger); diff --git a/pr/src/io/prmwait.c b/pr/src/io/prmwait.c index a48fbc19..65ea1cd6 100644 --- a/pr/src/io/prmwait.c +++ b/pr/src/io/prmwait.c @@ -58,19 +58,8 @@ typedef struct TimerEvent { struct { PRLock *ml; PRCondVar *new_timer; - PRCondVar *cancel_timer; /* The cancel_timer condition variable is - * used to cancel a timer (i.e., remove a - * timer event from the timer queue). At - * startup I'm borrowing this condition - * variable for a different purpose (to - * tell the primordial thread that the - * timer manager thread has started) so - * that I don't need to create a new - * condition variable just for this one - * time use. - */ + PRCondVar *cancel_timer; PRThread *manager_thread; - PRBool manager_started; PRCList timer_queue; } tm_vars; @@ -88,11 +77,6 @@ static void TimerManager(void *arg) TimerEvent *timer; PR_Lock(tm_vars.ml); - /* tell the primordial thread that we have started */ - tm_vars.manager_started = PR_TRUE; - if (!_native_threads_only) { - PR_NotifyCondVar(tm_vars.cancel_timer); - } while (1) { if (PR_CLIST_IS_EMPTY(&tm_vars.timer_queue)) @@ -216,16 +200,6 @@ static PRStatus TimerInit(void) { goto failed; } - /* - * Need to wait until the timer manager thread starts - * if the timer manager thread is a local thread. - */ - if (!_native_threads_only) { - PR_Lock(tm_vars.ml); - while (!tm_vars.manager_started) - PR_WaitCondVar(tm_vars.cancel_timer, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(tm_vars.ml); - } return PR_SUCCESS; failed: @@ -269,6 +243,17 @@ void _PR_InitMW(void) max_polling_interval = PR_MillisecondsToInterval(MAX_POLLING_INTERVAL); } /* _PR_InitMW */ +void _PR_CleanupMW(void) +{ + PR_DestroyLock(mw_lock); + mw_lock = NULL; + if (mw_state->group) { + PR_DestroyWaitGroup(mw_state->group); + /* mw_state->group is set to NULL as a side effect. */ + } + PR_DELETE(mw_state); +} /* _PR_CleanupMW */ + static PRWaitGroup *MW_Init2(void) { PRWaitGroup *group = mw_state->group; /* it's the null group */ diff --git a/pr/src/io/prprf.c b/pr/src/io/prprf.c index 2d6a78d8..5f4de6f4 100644 --- a/pr/src/io/prprf.c +++ b/pr/src/io/prprf.c @@ -51,8 +51,12 @@ ** Note: on some platforms va_list is defined as an array, ** and requires array notation. */ -#if (defined(LINUX) && defined(__powerpc__)) || defined(WIN16) || \ - defined(QNX) || \ +#if (defined(LINUX) && defined(__x86_64__)) +#define VARARGS_ASSIGN(foo, bar) __va_copy((foo), (bar)) +#elif (defined(LINUX) && defined(__powerpc__)) || \ + (defined(LINUX) && defined(__s390__)) || \ + (defined(LINUX) && defined(__s390x__)) || \ + defined(WIN16) || defined(QNX) || \ (defined(__NetBSD__) && defined(__powerpc__) && \ __NetBSD_Version__ < 105000000) #define VARARGS_ASSIGN(foo, bar) foo[0] = bar[0] @@ -89,9 +93,6 @@ struct NumArgState{ va_list ap; /* point to the corresponding position on ap */ }; -static PRBool l10n_debug_init = PR_FALSE; -static PRBool l10n_debug = PR_FALSE; - #define NAS_DEFAULT_NUM 20 /* default number of NumberedArgumentState array */ @@ -108,11 +109,11 @@ static PRBool l10n_debug = PR_FALSE; #define TYPE_INTSTR 10 #define TYPE_UNKNOWN 20 -#define _LEFT 0x1 -#define _SIGNED 0x2 -#define _SPACED 0x4 -#define _ZEROS 0x8 -#define _NEG 0x10 +#define FLAG_LEFT 0x1 +#define FLAG_SIGNED 0x2 +#define FLAG_SPACED 0x4 +#define FLAG_ZEROS 0x8 +#define FLAG_NEG 0x10 /* ** Fill into the buffer using the data in src @@ -124,8 +125,8 @@ static int fill2(SprintfState *ss, const char *src, int srclen, int width, int rv; width -= srclen; - if ((width > 0) && ((flags & _LEFT) == 0)) { /* Right adjusting */ - if (flags & _ZEROS) { + if ((width > 0) && ((flags & FLAG_LEFT) == 0)) { /* Right adjusting */ + if (flags & FLAG_ZEROS) { space = '0'; } while (--width >= 0) { @@ -142,7 +143,7 @@ static int fill2(SprintfState *ss, const char *src, int srclen, int width, return rv; } - if ((width > 0) && ((flags & _LEFT) != 0)) { /* Left adjusting */ + if ((width > 0) && ((flags & FLAG_LEFT) != 0)) { /* Left adjusting */ while (--width >= 0) { rv = (*ss->stuff)(ss, &space, 1); if (rv < 0) { @@ -169,13 +170,13 @@ static int fill_n(SprintfState *ss, const char *src, int srclen, int width, char sign; if ((type & 1) == 0) { - if (flags & _NEG) { + if (flags & FLAG_NEG) { sign = '-'; signwidth = 1; - } else if (flags & _SIGNED) { + } else if (flags & FLAG_SIGNED) { sign = '+'; signwidth = 1; - } else if (flags & _SPACED) { + } else if (flags & FLAG_SPACED) { sign = ' '; signwidth = 1; } @@ -189,14 +190,14 @@ static int fill_n(SprintfState *ss, const char *src, int srclen, int width, } } - if ((flags & _ZEROS) && (prec < 0)) { + if ((flags & FLAG_ZEROS) && (prec < 0)) { if (width > cvtwidth) { zerowidth = width - cvtwidth; /* Zero filling */ cvtwidth += zerowidth; } } - if (flags & _LEFT) { + if (flags & FLAG_LEFT) { if (width > cvtwidth) { /* Space filling on the right (i.e. left adjusting) */ rightspaces = width - cvtwidth; @@ -412,20 +413,6 @@ static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv, /* - ** set the l10n_debug flag - ** this routine should be executed only once - ** 'cause getenv does take time - */ - if( !l10n_debug_init ){ - l10n_debug_init = PR_TRUE; - p = getenv( "NETSCAPE_LOCALIZATION_DEBUG" ); - if( ( p != NULL ) && ( *p == '1' ) ){ - l10n_debug = PR_TRUE; - } - } - - - /* ** first pass: ** detemine how many legal % I have got, then allocate space */ @@ -444,23 +431,17 @@ static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv, if( c == '$' ){ /* numbered argument csae */ if( i > 0 ){ *rv = -1; - if( l10n_debug ) - printf( "either no *OR* all arguments are numbered \"%s\"\n", fmt ); return NULL; } number++; - break; - } else{ /* non-numbered argument case */ if( number > 0 ){ - if( l10n_debug ) - printf( "either no *OR* all arguments are numbered \"%s\"\n", fmt ); *rv = -1; return NULL; } i = 1; - break; } + break; } c = *p++; @@ -476,8 +457,6 @@ static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv, nas = (struct NumArgState*)PR_MALLOC( number * sizeof( struct NumArgState ) ); if( !nas ){ *rv = -1; - if( l10n_debug ) - printf( "PR_MALLOC() error for \"%s\"\n", fmt ); return NULL; } } else { @@ -508,8 +487,6 @@ static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv, if( !c || cn < 1 || cn > number ){ *rv = -1; - if( l10n_debug ) - printf( "invalid argument number (valid range [1, %d]), \"%s\"\n", number, fmt ); break; } @@ -524,13 +501,11 @@ static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv, if (c == '*') { /* not supported feature, for the argument is not numbered */ *rv = -1; - if( l10n_debug ) - printf( "* width specifier not support for numbered arguments \"%s\"\n", fmt ); break; - } else { - while ((c >= '0') && (c <= '9')) { - c = *p++; - } + } + + while ((c >= '0') && (c <= '9')) { + c = *p++; } /* precision */ @@ -538,14 +513,12 @@ static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv, c = *p++; if (c == '*') { /* not supported feature, for the argument is not numbered */ - if( l10n_debug ) - printf( "* precision specifier not support for numbered arguments \"%s\"\n", fmt ); *rv = -1; break; - } else { - while ((c >= '0') && (c <= '9')) { - c = *p++; - } + } + + while ((c >= '0') && (c <= '9')) { + c = *p++; } } @@ -622,8 +595,6 @@ static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv, /* get a legal para. */ if( nas[ cn ].type == TYPE_UNKNOWN ){ - if( l10n_debug ) - printf( "unknown type \"%s\"\n", fmt ); *rv = -1; break; } @@ -757,8 +728,6 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) } if( nas[i-1].type == TYPE_UNKNOWN ){ - if( l10n_debug ) - printf( "numbered argument type unknown\n" ); if( nas && ( nas != nasArray ) ) PR_DELETE( nas ); return -1; @@ -777,14 +746,14 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) * on this feature. */ while ((c == '-') || (c == '+') || (c == ' ') || (c == '0')) { - if (c == '-') flags |= _LEFT; - if (c == '+') flags |= _SIGNED; - if (c == ' ') flags |= _SPACED; - if (c == '0') flags |= _ZEROS; + if (c == '-') flags |= FLAG_LEFT; + if (c == '+') flags |= FLAG_SIGNED; + if (c == ' ') flags |= FLAG_SPACED; + if (c == '0') flags |= FLAG_ZEROS; c = *fmt++; } - if (flags & _SIGNED) flags &= ~_SPACED; - if (flags & _LEFT) flags &= ~_ZEROS; + if (flags & FLAG_SIGNED) flags &= ~FLAG_SPACED; + if (flags & FLAG_LEFT) flags &= ~FLAG_ZEROS; /* width */ if (c == '*') { @@ -866,7 +835,7 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) u.l = va_arg(ap, int); if (u.l < 0) { u.l = -u.l; - flags |= _NEG; + flags |= FLAG_NEG; } goto do_long; case TYPE_UINT16: @@ -876,7 +845,7 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) u.l = va_arg(ap, int); if (u.l < 0) { u.l = -u.l; - flags |= _NEG; + flags |= FLAG_NEG; } goto do_long; case TYPE_UINTN: @@ -887,7 +856,7 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) u.l = va_arg(ap, PRInt32); if (u.l < 0) { u.l = -u.l; - flags |= _NEG; + flags |= FLAG_NEG; } goto do_long; case TYPE_UINT32: @@ -903,7 +872,7 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) u.ll = va_arg(ap, PRInt64); if (!LL_GE_ZERO(u.ll)) { LL_NEG(u.ll, u.ll); - flags |= _NEG; + flags |= FLAG_NEG; } goto do_longlong; case TYPE_UINT64: @@ -939,7 +908,7 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) case 'c': u.ch = va_arg(ap, int); - if ((flags & _LEFT) == 0) { + if ((flags & FLAG_LEFT) == 0) { while (width-- > 1) { rv = (*ss->stuff)(ss, " ", 1); if (rv < 0) { @@ -951,7 +920,7 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) if (rv < 0) { return rv; } - if (flags & _LEFT) { + if (flags & FLAG_LEFT) { while (width-- > 1) { rv = (*ss->stuff)(ss, " ", 1); if (rv < 0) { @@ -1044,7 +1013,7 @@ PR_IMPLEMENT(PRUint32) PR_sxprintf(PRStuffFunc func, void *arg, const char *fmt, ...) { va_list ap; - int rv; + PRUint32 rv; va_start(ap, fmt); rv = PR_vsxprintf(func, arg, fmt, ap); @@ -1168,7 +1137,7 @@ static int LimitStuff(SprintfState *ss, const char *sp, PRUint32 len) PR_IMPLEMENT(PRUint32) PR_snprintf(char *out, PRUint32 outlen, const char *fmt, ...) { va_list ap; - int rv; + PRUint32 rv; PR_ASSERT((PRInt32)outlen > 0); if ((PRInt32)outlen <= 0) { diff --git a/pr/src/io/prsocket.c b/pr/src/io/prsocket.c index 2483f963..999fc03d 100644 --- a/pr/src/io/prsocket.c +++ b/pr/src/io/prsocket.c @@ -44,7 +44,7 @@ PRBool IsValidNetAddr(const PRNetAddr *addr) { if ((addr != NULL) -#ifdef XP_UNIX +#if defined(XP_UNIX) || defined(XP_OS2) && (addr->raw.family != PR_AF_LOCAL) #endif && (addr->raw.family != PR_AF_INET6) @@ -61,7 +61,7 @@ static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len) * is not uniform, so we don't check it. */ if ((addr != NULL) -#ifdef XP_UNIX +#if defined(XP_UNIX) || defined(XP_OS2) && (addr->raw.family != AF_UNIX) #endif && (PR_NETADDR_SIZE(addr) != addr_len)) { @@ -338,27 +338,16 @@ static PRStatus PR_CALLBACK SocketConnectContinue( #elif defined(XP_OS2) - if (out_flags & PR_POLL_EXCEPT) { - int len = sizeof(err); - if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &len) - < 0) { - _PR_MD_MAP_GETSOCKOPT_ERROR(sock_errno()); - return PR_FAILURE; - } - if (err != 0) { - _PR_MD_MAP_CONNECT_ERROR(err); - } else { - PR_SetError(PR_UNKNOWN_ERROR, 0); - } + err = _MD_os2_get_nonblocking_connect_error(osfd); + if (err != 0) { + _PR_MD_MAP_CONNECT_ERROR(err); return PR_FAILURE; } - - PR_ASSERT(out_flags & PR_POLL_WRITE); return PR_SUCCESS; #elif defined(XP_MAC) - err = _MD_mac_get_nonblocking_connect_error(osfd); + err = _MD_mac_get_nonblocking_connect_error(fd); if (err == -1) return PR_FAILURE; else @@ -366,13 +355,23 @@ static PRStatus PR_CALLBACK SocketConnectContinue( #elif defined(XP_BEOS) +#ifdef BONE_VERSION /* bug 122364 */ + /* temporary workaround until getsockopt(SO_ERROR) works in BONE */ + if (out_flags & PR_POLL_EXCEPT) { + PR_SetError(PR_CONNECT_REFUSED_ERROR, 0); + return PR_FAILURE; + } + PR_ASSERT(out_flags & PR_POLL_WRITE); + return PR_SUCCESS; +#else err = _MD_beos_get_nonblocking_connect_error(fd); if( err != 0 ) { - _PR_MD_MAP_CONNECT_ERROR(err); - return PR_FAILURE; + _PR_MD_MAP_CONNECT_ERROR(err); + return PR_FAILURE; } else - return PR_SUCCESS; + return PR_SUCCESS; +#endif /* BONE_VERSION */ #else PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); @@ -1274,7 +1273,7 @@ PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto) if (!_pr_initialized) _PR_ImplicitInitialization(); if (PR_AF_INET != domain && PR_AF_INET6 != domain -#if defined(XP_UNIX) +#if defined(XP_UNIX) || defined(XP_OS2) && PR_AF_LOCAL != domain #endif ) { @@ -1396,7 +1395,7 @@ PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *f[]) */ SOCKET listenSock; SOCKET osfd[2]; - struct sockaddr_in selfAddr; + struct sockaddr_in selfAddr, peerAddr; int addrLen; if (!_pr_initialized) _PR_ImplicitInitialization(); @@ -1440,10 +1439,24 @@ PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *f[]) addrLen) == SOCKET_ERROR) { goto failed; } - osfd[1] = accept(listenSock, NULL, NULL); + /* + * A malicious local process may connect to the listening + * socket, so we need to verify that the accepted connection + * is made from our own socket osfd[0]. + */ + if (getsockname(osfd[0], (struct sockaddr *) &selfAddr, + &addrLen) == SOCKET_ERROR) { + goto failed; + } + osfd[1] = accept(listenSock, (struct sockaddr *) &peerAddr, &addrLen); if (osfd[1] == INVALID_SOCKET) { goto failed; } + if (peerAddr.sin_port != selfAddr.sin_port) { + /* the connection we accepted is not from osfd[0] */ + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + goto failed; + } closesocket(listenSock); f[0] = PR_AllocFileDesc(osfd[0], PR_GetTCPMethods()); @@ -1480,7 +1493,7 @@ failed: * default implementation */ PRFileDesc *listenSock; - PRNetAddr selfAddr; + PRNetAddr selfAddr, peerAddr; PRUint16 port; f[0] = f[1] = NULL; @@ -1503,6 +1516,17 @@ failed: if (f[0] == NULL) { goto failed; } +#ifdef _PR_CONNECT_DOES_NOT_BIND + /* + * If connect does not implicitly bind the socket (e.g., on + * BeOS), we have to bind the socket so that we can get its + * port with getsockname later. + */ + PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr); + if (PR_Bind(f[0], &selfAddr) == PR_FAILURE) { + goto failed; + } +#endif PR_InitializeNetAddr(PR_IpAddrLoopback, port, &selfAddr); /* @@ -1518,10 +1542,23 @@ failed: == PR_FAILURE) { goto failed; } - f[1] = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); + /* + * A malicious local process may connect to the listening + * socket, so we need to verify that the accepted connection + * is made from our own socket f[0]. + */ + if (PR_GetSockName(f[0], &selfAddr) == PR_FAILURE) { + goto failed; + } + f[1] = PR_Accept(listenSock, &peerAddr, PR_INTERVAL_NO_TIMEOUT); if (f[1] == NULL) { goto failed; } + if (peerAddr.inet.port != selfAddr.inet.port) { + /* the connection we accepted is not from f[0] */ + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + goto failed; + } PR_Close(listenSock); return PR_SUCCESS; @@ -1532,6 +1569,9 @@ failed: if (f[0]) { PR_Close(f[0]); } + if (f[1]) { + PR_Close(f[1]); + } return PR_FAILURE; #endif } @@ -1539,20 +1579,14 @@ failed: PR_IMPLEMENT(PRInt32) PR_FileDesc2NativeHandle(PRFileDesc *fd) { - if (fd) { - /* - * The fd may be layered. Chase the links to the - * bottom layer to get the osfd. - */ - PRFileDesc *bottom = fd; - while (bottom->lower != NULL) { - bottom = bottom->lower; - } - return bottom->secret->md.osfd; - } else { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return -1; - } + if (fd) { + fd = PR_GetIdentitiesLayer(fd, PR_NSPR_IO_LAYER); + } + if (!fd) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + return fd->secret->md.osfd; } PR_IMPLEMENT(void) diff --git a/pr/src/io/prstdio.c b/pr/src/io/prstdio.c index 4ae2f267..de4c39de 100644 --- a/pr/src/io/prstdio.c +++ b/pr/src/io/prstdio.c @@ -56,7 +56,45 @@ PR_IMPLEMENT(PRUint32) PR_vfprintf(PRFileDesc* fd, const char *fmt, va_list ap) PRUint32 rv, len; char* msg = PR_vsmprintf(fmt, ap); len = strlen(msg); +#ifdef XP_OS2 + /* + * OS/2 really needs a \r for every \n. + * In the future we should try to use scatter-gather instead of a + * succession of PR_Write. + */ + if (isatty(PR_FileDesc2NativeHandle(fd))) { + PRUint32 last = 0, idx; + PRInt32 tmp; + rv = 0; + for (idx = 0; idx < len+1; idx++) { + if ((idx - last > 0) && (('\n' == msg[idx]) || (idx == len))) { + tmp = PR_Write(fd, msg + last, idx - last); + if (tmp >= 0) { + rv += tmp; + } + last = idx; + } + /* + * if current character is \n, and + * previous character isn't \r, and + * next character isn't \r + */ + if (('\n' == msg[idx]) && + ((0 == idx) || ('\r' != msg[idx-1])) && + ('\r' != msg[idx+1])) { + /* add extra \r */ + tmp = PR_Write(fd, "\r", 1); + if (tmp >= 0) { + rv += tmp; + } + } + } + } else { + rv = PR_Write(fd, msg, len); + } +#else rv = PR_Write(fd, msg, len); +#endif PR_DELETE(msg); return rv; } |