summaryrefslogtreecommitdiff
path: root/pr/src/md
diff options
context:
space:
mode:
authorwtc%netscape.com <devnull@localhost>1998-12-09 16:37:26 +0000
committerwtc%netscape.com <devnull@localhost>1998-12-09 16:37:26 +0000
commit7fe2fa921cdd716afa2d5c54f7e8de94879f0993 (patch)
tree1873fd232abdcc7b08d6c023daa8de7af4b59dae /pr/src/md
parent44b2a1483226959769305464c0e11ee7a0851503 (diff)
downloadnspr-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.c9
-rw-r--r--pr/src/md/unix/unix.c19
-rw-r--r--pr/src/md/unix/uxproces.c37
-rw-r--r--pr/src/md/windows/ntio.c16
-rw-r--r--pr/src/md/windows/ntmisc.c46
-rw-r--r--pr/src/md/windows/ntthread.c72
-rw-r--r--pr/src/md/windows/w95io.c16
-rw-r--r--pr/src/md/windows/w95thred.c50
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;
}