diff options
author | wtc%netscape.com <devnull@localhost> | 1998-12-09 16:37:26 +0000 |
---|---|---|
committer | wtc%netscape.com <devnull@localhost> | 1998-12-09 16:37:26 +0000 |
commit | 7fe2fa921cdd716afa2d5c54f7e8de94879f0993 (patch) | |
tree | 1873fd232abdcc7b08d6c023daa8de7af4b59dae /pr/src/md | |
parent | 44b2a1483226959769305464c0e11ee7a0851503 (diff) | |
download | nspr-hg-7fe2fa921cdd716afa2d5c54f7e8de94879f0993.tar.gz |
This checkin consists on three things:
1. File descriptor inheritance
2. Set thread->md.handle on Win32 for attached native threads.
3. Miscellaneous code cleanup.
Diffstat (limited to 'pr/src/md')
-rw-r--r-- | pr/src/md/os2/os2thred.c | 9 | ||||
-rw-r--r-- | pr/src/md/unix/unix.c | 19 | ||||
-rw-r--r-- | pr/src/md/unix/uxproces.c | 37 | ||||
-rw-r--r-- | pr/src/md/windows/ntio.c | 16 | ||||
-rw-r--r-- | pr/src/md/windows/ntmisc.c | 46 | ||||
-rw-r--r-- | pr/src/md/windows/ntthread.c | 72 | ||||
-rw-r--r-- | pr/src/md/windows/w95io.c | 16 | ||||
-rw-r--r-- | pr/src/md/windows/w95thred.c | 50 |
8 files changed, 194 insertions, 71 deletions
diff --git a/pr/src/md/os2/os2thred.c b/pr/src/md/os2/os2thred.c index ecc25e57..41947c0d 100644 --- a/pr/src/md/os2/os2thred.c +++ b/pr/src/md/os2/os2thred.c @@ -60,8 +60,8 @@ _PR_MD_EARLY_INIT() #endif } -PR_IMPLEMENT(void) -_PR_MD_INIT_PRIMORDIAL_THREAD(PRThread *thread) +static void +_pr_SetThreadMDHandle(PRThread *thread) { PTIB ptib; PPIB ppib; @@ -76,8 +76,9 @@ _PR_MD_INIT_PRIMORDIAL_THREAD(PRThread *thread) PR_IMPLEMENT(PRStatus) _PR_MD_INIT_THREAD(PRThread *thread) { - if (thread->flags & _PR_PRIMORDIAL) - _PR_MD_INIT_PRIMORDIAL_THREAD(thread); + if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) { + _pr_SetThreadMDHandle(thread); + } /* Create the blocking IO semaphore */ _PR_MD_NEW_SEM(&thread->md.blocked_sema, 1); diff --git a/pr/src/md/unix/unix.c b/pr/src/md/unix/unix.c index 72922f1d..cafd3b1b 100644 --- a/pr/src/md/unix/unix.c +++ b/pr/src/md/unix/unix.c @@ -1271,6 +1271,18 @@ PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level, return rv==0?PR_SUCCESS:PR_FAILURE; } +PRStatus _MD_set_fd_inheritable(PRFileDesc *fd, PRBool inheritable) +{ + int rv; + + rv = fcntl(fd->secret->md.osfd, F_SETFD, inheritable ? 0 : FD_CLOEXEC); + if (-1 == rv) { + PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO()); + return PR_FAILURE; + } + return PR_SUCCESS; +} + /************************************************************************/ #if !defined(_PR_USE_POLL) @@ -2082,6 +2094,13 @@ void _MD_UnblockClockInterrupts() sigprocmask(SIG_UNBLOCK, &timer_set, 0); } +void _MD_InitFileDesc(PRFileDesc *fd) +{ + /* By default, a Unix fd is not closed on exec. */ + PR_ASSERT(0 == fcntl(fd->secret->md.osfd, F_GETFD, 0)); + fd->secret->inheritable = PR_TRUE; +} + void _MD_MakeNonblock(PRFileDesc *fd) { PRInt32 osfd = fd->secret->md.osfd; diff --git a/pr/src/md/unix/uxproces.c b/pr/src/md/unix/uxproces.c index c2b7eee5..6b1d4110 100644 --- a/pr/src/md/unix/uxproces.c +++ b/pr/src/md/unix/uxproces.c @@ -27,6 +27,8 @@ #include <dlfcn.h> /* For dlopen, dlsym, dlclose */ #endif +extern char **environ; + /* * HP-UX 9 doesn't have the SA_RESTART flag. */ @@ -140,6 +142,9 @@ ForkAndExec( const PRProcessAttr *attr) { PRProcess *process; + int nEnv, idx; + char *const *childEnvp; + char **newEnvp = NULL; process = PR_NEW(PRProcess); if (!process) { @@ -147,6 +152,27 @@ ForkAndExec( return NULL; } + childEnvp = envp; + if (attr && attr->fdInheritBuffer) { + if (NULL == childEnvp) { + childEnvp = environ; + } + for (nEnv = 0; childEnvp[nEnv]; nEnv++) { + } + newEnvp = (char **) PR_MALLOC((nEnv + 2) * sizeof(char *)); + if (NULL == newEnvp) { + PR_DELETE(process); + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; + } + for (idx = 0; idx < nEnv; idx++) { + newEnvp[idx] = childEnvp[idx]; + } + newEnvp[idx++] = attr->fdInheritBuffer; + newEnvp[idx] = NULL; + childEnvp = newEnvp; + } + #ifdef AIX process->md.pid = (*pr_wp.forkptr)(); #else @@ -155,6 +181,9 @@ ForkAndExec( if ((pid_t) -1 == process->md.pid) { PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, errno); PR_DELETE(process); + if (newEnvp) { + PR_DELETE(newEnvp); + } return NULL; } else if (0 == process->md.pid) { /* the child process */ /* @@ -193,8 +222,8 @@ ForkAndExec( } } - if (envp) { - (void)execve(path, argv, envp); + if (childEnvp) { + (void)execve(path, argv, childEnvp); } else { /* Inherit the environment of the parent. */ (void)execv(path, argv); @@ -203,6 +232,10 @@ ForkAndExec( _exit(1); } + if (newEnvp) { + PR_DELETE(newEnvp); + } + #if defined(_PR_NATIVE_THREADS) PR_Lock(pr_wp.ml); if (0 == pr_wp.numProcs++) { diff --git a/pr/src/md/windows/ntio.c b/pr/src/md/windows/ntio.c index 0e09cd8b..537bb652 100644 --- a/pr/src/md/windows/ntio.c +++ b/pr/src/md/windows/ntio.c @@ -2177,6 +2177,22 @@ _PR_MD_CLOSE(PRInt32 osfd, PRBool socket) } } +PRStatus +_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable) +{ + BOOL rv; + + rv = SetHandleInformation( + (HANDLE)fd->secret->md.osfd, + HANDLE_FLAG_INHERIT, + inheritable ? HANDLE_FLAG_INHERIT : 0); + if (0 == rv) { + PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); + return PR_FAILURE; + } + return PR_SUCCESS; +} + /* --- DIR IO ------------------------------------------------------------ */ #define GetFileFromDIR(d) (d)->d_entry.cFileName diff --git a/pr/src/md/windows/ntmisc.c b/pr/src/md/windows/ntmisc.c index 869bc897..ea393333 100644 --- a/pr/src/md/windows/ntmisc.c +++ b/pr/src/md/windows/ntmisc.c @@ -353,8 +353,8 @@ PRProcess * _PR_CreateWindowsProcess( BOOL retVal; char *cmdLine = NULL; char *envBlock = NULL; - char **newEnvp; - char *cwd = NULL; /* current working directory */ + char **newEnvp = NULL; + const char *cwd = NULL; /* current working directory */ PRProcess *proc = NULL; proc = PR_NEW(PRProcess); @@ -368,19 +368,37 @@ PRProcess * _PR_CreateWindowsProcess( goto errorExit; } - if (envp == NULL) { - newEnvp = NULL; - } else { - int i; - int numEnv = 0; + /* + * If attr->fdInheritBuffer is not NULL, we need to insert + * it into the envp array, so envp cannot be NULL. + */ + if ((envp == NULL) && attr && attr->fdInheritBuffer) { + envp = environ; + } + + if (envp != NULL) { + int idx; + int numEnv; + int newEnvpSize; + + numEnv = 0; while (envp[numEnv]) { numEnv++; } - newEnvp = (char **) PR_MALLOC((numEnv+1) * sizeof(char *)); - for (i = 0; i <= numEnv; i++) { - newEnvp[i] = envp[i]; + newEnvpSize = numEnv + 1; /* terminating null pointer */ + if (attr && attr->fdInheritBuffer) { + newEnvpSize++; + } + newEnvp = (char **) PR_MALLOC(newEnvpSize * sizeof(char *)); + for (idx = 0; idx < numEnv; idx++) { + newEnvp[idx] = envp[idx]; + } + if (attr && attr->fdInheritBuffer) { + newEnvp[idx++] = attr->fdInheritBuffer; } - qsort((void *) newEnvp, (size_t) numEnv, sizeof(char *), compare); + newEnvp[idx] = NULL; + qsort((void *) newEnvp, (size_t) (newEnvpSize - 1), + sizeof(char *), compare); } if (assembleEnvBlock(newEnvp, &envBlock) == -1) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); @@ -448,6 +466,9 @@ PRProcess * _PR_CreateWindowsProcess( proc->md.id = procInfo.dwProcessId; PR_DELETE(cmdLine); + if (newEnvp) { + PR_DELETE(newEnvp); + } if (envBlock) { PR_DELETE(envBlock); } @@ -457,6 +478,9 @@ errorExit: if (cmdLine) { PR_DELETE(cmdLine); } + if (newEnvp) { + PR_DELETE(newEnvp); + } if (envBlock) { PR_DELETE(envBlock); } diff --git a/pr/src/md/windows/ntthread.c b/pr/src/md/windows/ntthread.c index 1f6de5ac..6697496d 100644 --- a/pr/src/md/windows/ntthread.c +++ b/pr/src/md/windows/ntthread.c @@ -127,37 +127,41 @@ void _PR_MD_CLEANUP_BEFORE_EXIT(void) } } -void -_PR_MD_INIT_PRIMORDIAL_THREAD(PRThread *thread) -{ - /* - ** Warning: - ** -------- - ** NSPR requires a real handle to every thread. GetCurrentThread() - ** returns a pseudo-handle which is not suitable for some thread - ** operations (ie. suspending). Therefore, get a real handle from - ** the pseudo handle via DuplicateHandle(...) - */ - DuplicateHandle( GetCurrentProcess(), /* Process of source handle */ - GetCurrentThread(), /* Pseudo Handle to dup */ - GetCurrentProcess(), /* Process of handle */ - &(thread->md.handle), /* resulting handle */ - 0L, /* access flags */ - FALSE, /* Inheritable */ - DUPLICATE_SAME_ACCESS ); /* Options */ -} - PRStatus _PR_MD_INIT_THREAD(PRThread *thread) { thread->md.overlapped.ioModel = _MD_BlockingIO; thread->md.overlapped.data.mdThread = &thread->md; - /* Create the blocking IO semaphore */ - thread->md.blocked_sema = CreateSemaphore(NULL, 0, 1, NULL); - if (thread->md.blocked_sema == NULL) - return PR_FAILURE; - else - return PR_SUCCESS; + + if (thread->flags & _PR_GLOBAL_SCOPE) { + if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) { + /* + ** Warning: + ** -------- + ** NSPR requires a real handle to every thread. + ** GetCurrentThread() returns a pseudo-handle which + ** is not suitable for some thread operations (e.g., + ** suspending). Therefore, get a real handle from + ** the pseudo handle via DuplicateHandle(...) + */ + DuplicateHandle( + GetCurrentProcess(), /* Process of source handle */ + GetCurrentThread(), /* Pseudo Handle to dup */ + GetCurrentProcess(), /* Process of handle */ + &(thread->md.handle), /* resulting handle */ + 0L, /* access flags */ + FALSE, /* Inheritable */ + DUPLICATE_SAME_ACCESS); /* Options */ + } + + /* Create the blocking IO semaphore */ + thread->md.blocked_sema = CreateSemaphore(NULL, 0, 1, NULL); + if (thread->md.blocked_sema == NULL) { + return PR_FAILURE; + } + } + + return PR_SUCCESS; } PRStatus @@ -259,6 +263,8 @@ _PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri) void _PR_MD_CLEAN_THREAD(PRThread *thread) { + BOOL rv; + if (thread->md.acceptex_buf) { PR_DELETE(thread->md.acceptex_buf); } @@ -268,12 +274,14 @@ _PR_MD_CLEAN_THREAD(PRThread *thread) } if (thread->md.blocked_sema) { - CloseHandle(thread->md.blocked_sema); + rv = CloseHandle(thread->md.blocked_sema); + PR_ASSERT(rv); thread->md.blocked_sema = 0; } if (thread->md.handle) { - CloseHandle(thread->md.handle); + rv = CloseHandle(thread->md.handle); + PR_ASSERT(rv); thread->md.handle = 0; } @@ -293,6 +301,8 @@ _PR_MD_CLEAN_THREAD(PRThread *thread) void _PR_MD_EXIT_THREAD(PRThread *thread) { + BOOL rv; + if (thread->md.acceptex_buf) { PR_DELETE(thread->md.acceptex_buf); } @@ -302,12 +312,14 @@ _PR_MD_EXIT_THREAD(PRThread *thread) } if (thread->md.blocked_sema) { - CloseHandle(thread->md.blocked_sema); + rv = CloseHandle(thread->md.blocked_sema); + PR_ASSERT(rv); thread->md.blocked_sema = 0; } if (thread->md.handle) { - CloseHandle(thread->md.handle); + rv = CloseHandle(thread->md.handle); + PR_ASSERT(rv); thread->md.handle = 0; } diff --git a/pr/src/md/windows/w95io.c b/pr/src/md/windows/w95io.c index 173a3a58..3c7a67c1 100644 --- a/pr/src/md/windows/w95io.c +++ b/pr/src/md/windows/w95io.c @@ -754,6 +754,22 @@ _PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info) return rv; } +PRStatus +_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable) +{ + BOOL rv; + + rv = SetHandleInformation( + (HANDLE)fd->secret->md.osfd, + HANDLE_FLAG_INHERIT, + inheritable ? HANDLE_FLAG_INHERIT : 0); + if (0 == rv) { + PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); + return PR_FAILURE; + } + return PR_SUCCESS; +} + PRInt32 _PR_MD_RENAME(const char *from, const char *to) { diff --git a/pr/src/md/windows/w95thred.c b/pr/src/md/windows/w95thred.c index 89103bb2..c911bf13 100644 --- a/pr/src/md/windows/w95thred.c +++ b/pr/src/md/windows/w95thred.c @@ -57,31 +57,28 @@ void _PR_MD_CLEANUP_BEFORE_EXIT(void) #endif } -void -_PR_MD_INIT_PRIMORDIAL_THREAD(PRThread *thread) -{ - /* - ** Warning: - ** -------- - ** NSPR requires a real handle to every thread. GetCurrentThread() - ** returns a pseudo-handle which is not suitable for some thread - ** operations (ie. suspending). Therefore, get a real handle from - ** the pseudo handle via DuplicateHandle(...) - */ - DuplicateHandle( GetCurrentProcess(), /* Process of source handle */ - GetCurrentThread(), /* Pseudo Handle to dup */ - GetCurrentProcess(), /* Process of handle */ - &(thread->md.handle), /* resulting handle */ - 0L, /* access flags */ - FALSE, /* Inheritable */ - DUPLICATE_SAME_ACCESS ); /* Options */ -} - PRStatus _PR_MD_INIT_THREAD(PRThread *thread) { - if (thread->flags & _PR_PRIMORDIAL) - _PR_MD_INIT_PRIMORDIAL_THREAD(thread); + if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) { + /* + ** Warning: + ** -------- + ** NSPR requires a real handle to every thread. + ** GetCurrentThread() returns a pseudo-handle which + ** is not suitable for some thread operations (e.g., + ** suspending). Therefore, get a real handle from + ** the pseudo handle via DuplicateHandle(...) + */ + DuplicateHandle( + GetCurrentProcess(), /* Process of source handle */ + GetCurrentThread(), /* Pseudo Handle to dup */ + GetCurrentProcess(), /* Process of handle */ + &(thread->md.handle), /* resulting handle */ + 0L, /* access flags */ + FALSE, /* Inheritable */ + DUPLICATE_SAME_ACCESS); /* Options */ + } /* Create the blocking IO semaphore */ thread->md.blocked_sema = CreateSemaphore(NULL, 0, 1, NULL); @@ -164,13 +161,17 @@ _PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri) void _PR_MD_CLEAN_THREAD(PRThread *thread) { + BOOL rv; + if (thread->md.blocked_sema) { - CloseHandle(thread->md.blocked_sema); + rv = CloseHandle(thread->md.blocked_sema); + PR_ASSERT(rv); thread->md.blocked_sema = 0; } if (thread->md.handle) { - CloseHandle(thread->md.handle); + rv = CloseHandle(thread->md.handle); + PR_ASSERT(rv); thread->md.handle = 0; } } @@ -254,4 +255,5 @@ PRThread *thread; PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0); } PR_ASSERT(thread != NULL); + return thread; } |