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.
This commit is contained in:
wtc%netscape.com 1998-12-09 16:37:26 +00:00
parent cc72577fd7
commit c9f4f25104
28 changed files with 465 additions and 115 deletions

View File

@ -377,7 +377,6 @@ PR_EXTERN(void) _MD_InitLocks(void);
PR_EXTERN(void) _MD_CleanThread(struct PRThread *thread);
#define _MD_CLEAN_THREAD _MD_CleanThread
#define _MD_INIT_PRIMORDIAL_THREAD(threadp)
#define _MD_YIELD() sginap(0)
/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and

View File

@ -377,6 +377,7 @@ extern PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, c
#define _MD_SENDTO _MD_sendto
#define _MD_RECVFROM _MD_recvfrom
#define _MD_PR_POLL _MD_poll
#define _MD_INIT_FILEDESC(fd)
#define _MD_MAKE_NONBLOCK _MD_makenonblock
#define _MD_GET_SOCKET_ERROR() _PR_MD_CURRENT_THREAD()->md.osErrCode
@ -450,7 +451,6 @@ extern int _MD_PutEnv(const char *variableCopy);
#define GCPTR
#define CALLBACK
typedef int (*FARPROC)();
#define gcmemcpy(a,b,c) memcpy(a,b,c)
#define MAX_NON_PRIMARY_TIME_SLICES 6
@ -458,8 +458,6 @@ typedef int (*FARPROC)();
extern long gTimeSlicesOnNonPrimaryThread;
extern struct PRThread *gPrimaryThread;
typedef short PROSFD;
// Errors not found in the Mac StdCLib
#define EACCES 13 // Permission denied
#define ENOENT -43 // No such file or directory

View File

@ -231,8 +231,6 @@ PR_EXTERN(void) _MD_InitLocks(void);
PR_EXTERN(void) _MD_CleanThread(struct PRThread *thread);
#define _MD_CLEAN_THREAD _MD_CleanThread
#define _MD_INIT_PRIMORDIAL_THREAD(threadp)
PR_EXTERN(PRStatus) _MD_CreateThread(
struct PRThread *thread,
void (*start) (void *),

View File

@ -237,6 +237,7 @@ extern PRInt32 _MD_CloseFile(PRInt32 osfd);
/* #define INADDR_LOOPBACK INADDR_ANY */
#endif
#define _MD_INIT_FILEDESC(fd)
extern void _MD_MakeNonblock(PRFileDesc *f);
#define _MD_MAKE_NONBLOCK _MD_MakeNonblock
#define _MD_SHUTDOWN (_PR_MD_SHUTDOWN)
@ -302,7 +303,6 @@ extern PRInt32 _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
#define _MD_DEFAULT_STACK_SIZE 32767L
#define _MD_INIT_THREAD (_PR_MD_INIT_THREAD)
#define _MD_INIT_ATTACHED_THREAD (_PR_MD_INIT_THREAD)
#define _MD_INIT_PRIMORDIAL_THREAD (_PR_MD_INIT_PRIMORDIAL_THREAD)
#define _MD_CREATE_THREAD (_PR_MD_CREATE_THREAD)
#define _MD_YIELD (_PR_MD_YIELD)
#define _MD_SET_PRIORITY (_PR_MD_SET_PRIORITY)

View File

@ -21,13 +21,8 @@
#define PR_DLL_SUFFIX ".dll"
#ifndef OS2
#include <windows.h>
#endif
#include <setjmp.h>
#include <stdlib.h>
#define USE_SETJMP
#define DIRECTORY_SEPARATOR '\\'
#define DIRECTORY_SEPARATOR_STR "\\"
#define PATH_SEPARATOR ';'
@ -49,17 +44,12 @@ extern int getopt(int argc, char **argv, char *spec);
#endif
PR_END_EXTERN_C
#define gcmemcpy(a,b,c) memcpy(a,b,c)
/*
** Definitions of directory structures amd functions
** These definitions are from:
** <dirent.h>
*/
#ifdef MOZ_BITS
#include <time.h>
#endif
#ifdef XP_OS2_EMX
#include <sys/types.h>
#endif
@ -67,17 +57,6 @@ PR_END_EXTERN_C
#include <io.h>
#include <fcntl.h> /* O_BINARY */
typedef int PROSFD;
/*
** Undo the macro define in the Microsoft header files...
*/
#ifndef XP_OS2 /* Uh... this seems a bit insane in itself to we OS/2 folk */
#ifdef _stat
#undef _stat
#endif
#endif
#ifdef OS2
extern PRStatus _MD_OS2GetHostName(char *name, PRUint32 namelen);
#define _MD_GETHOSTNAME _MD_OS2GetHostName

View File

@ -268,6 +268,9 @@ extern void _MD_Wakeup_CPUs(void);
/************************************************************************/
extern void _MD_InitFileDesc(PRFileDesc *fd);
#define _MD_INIT_FILEDESC _MD_InitFileDesc
extern void _MD_MakeNonblock(PRFileDesc *fd);
#define _MD_MAKE_NONBLOCK _MD_MakeNonblock
@ -427,6 +430,9 @@ extern PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level,
PRInt32 optname, const char* optval, PRInt32 optlen);
#define _MD_SETSOCKOPT _MD_setsockopt
extern PRStatus _MD_set_fd_inheritable(PRFileDesc *fd, PRBool inheritable);
#define _MD_SET_FD_INHERITABLE _MD_set_fd_inheritable
extern PRStatus _MD_gethostname(char *name, PRUint32 namelen);
#define _MD_GETHOSTNAME _MD_gethostname

View File

@ -279,6 +279,7 @@ extern PRStatus _PR_KillWindowsProcess(struct PRProcess *process);
#define _MD_GET_SOCKET_ERROR() WSAGetLastError()
#define _MD_SET_SOCKET_ERROR(_err) WSASetLastError(_err)
#define _MD_INIT_FILEDESC(fd)
#define _MD_MAKE_NONBLOCK _PR_MD_MAKE_NONBLOCK
#define _MD_SHUTDOWN _PR_MD_SHUTDOWN
#define _MD_LISTEN _PR_MD_LISTEN
@ -337,7 +338,6 @@ extern PRStatus _PR_KillWindowsProcess(struct PRProcess *process);
/* --- Threading Stuff --- */
#define _MD_DEFAULT_STACK_SIZE 32767L
#define _MD_INIT_THREAD _PR_MD_INIT_THREAD
#define _MD_INIT_PRIMORDIAL_THREAD _PR_MD_INIT_PRIMORDIAL_THREAD
#define _MD_CREATE_THREAD(t,f,p,sc,st,stsiz) (PR_SUCCESS)
#define _MD_YIELD _PR_MD_YIELD
#define _MD_SET_PRIORITY(t,p)

View File

@ -207,6 +207,7 @@ extern PRInt32 _MD_CloseFile(PRInt32 osfd);
#define _MD_GET_SOCKET_ERROR() WSAGetLastError()
#define _MD_SET_SOCKET_ERROR(_err) WSASetLastError(_err)
#define _MD_INIT_FILEDESC(fd)
extern void _MD_MakeNonblock(PRFileDesc *f);
#define _MD_MAKE_NONBLOCK _MD_MakeNonblock
#define _MD_SHUTDOWN _PR_MD_SHUTDOWN
@ -220,6 +221,7 @@ extern PRInt32 _MD_CloseSocket(PRInt32 osfd);
#define _MD_GETPEERNAME _PR_MD_GETPEERNAME
#define _MD_GETSOCKOPT _PR_MD_GETSOCKOPT
#define _MD_SETSOCKOPT _PR_MD_SETSOCKOPT
#define _MD_SET_FD_INHERITABLE _PR_MD_SET_FD_INHERITABLE
#define _MD_SELECT select
#define _MD_FSYNC _PR_MD_FSYNC
#define READ_FD 1
@ -281,7 +283,6 @@ extern PRInt32 _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
#define _MD_DEFAULT_STACK_SIZE 0
#define _MD_INIT_THREAD _PR_MD_INIT_THREAD
#define _MD_INIT_ATTACHED_THREAD _PR_MD_INIT_THREAD
#define _MD_INIT_PRIMORDIAL_THREAD _PR_MD_INIT_PRIMORDIAL_THREAD
#define _MD_CREATE_THREAD _PR_MD_CREATE_THREAD
#define _MD_YIELD _PR_MD_YIELD
#define _MD_SET_PRIORITY _PR_MD_SET_PRIORITY

View File

@ -228,6 +228,7 @@ extern PRInt32 _PR_MD_CLOSE(PRInt32 osfd, PRBool socket);
#define _MD_GET_SOCKET_ERROR() WSAGetLastError()
#define _MD_SET_SOCKET_ERROR(_err) WSASetLastError(_err)
#define _MD_INIT_FILEDESC(fd)
#define _MD_MAKE_NONBLOCK _PR_MD_MAKE_NONBLOCK
#define _MD_SHUTDOWN _PR_MD_SHUTDOWN
#define _MD_LISTEN _PR_MD_LISTEN
@ -242,6 +243,7 @@ extern PRInt32 _PR_MD_CLOSE(PRInt32 osfd, PRBool socket);
#define _MD_SELECT select
#define _MD_FSYNC _PR_MD_FSYNC
#define _MD_SOCKETAVAILABLE _PR_MD_SOCKETAVAILABLE
#define _MD_SET_FD_INHERITABLE _PR_MD_SET_FD_INHERITABLE
#define _MD_INIT_ATOMIC()
#if defined(_M_IX86) || defined(_X86_)
@ -301,7 +303,6 @@ extern PRInt32 _PR_MD_CLOSE(PRInt32 osfd, PRBool socket);
#define _MD_DEFAULT_STACK_SIZE 0
#define _MD_INIT_THREAD _PR_MD_INIT_THREAD
#define _MD_INIT_ATTACHED_THREAD _PR_MD_INIT_THREAD
#define _MD_INIT_PRIMORDIAL_THREAD _PR_MD_INIT_PRIMORDIAL_THREAD
#define _MD_CREATE_THREAD _PR_MD_CREATE_THREAD
#define _MD_YIELD _PR_MD_YIELD
#define _MD_SET_PRIORITY _PR_MD_SET_PRIORITY

View File

@ -71,7 +71,6 @@ extern void bcopy(const char *, char *, int);
** SA_RESTART to 0.
*/
#define SA_RESTART 0
#define SA_SIGINFO 0
/* stdio.h */
extern int printf(const char *, ...);

View File

@ -1506,6 +1506,55 @@ PR_EXTERN(PRStatus) PR_GetSocketOption(
PR_EXTERN(PRStatus) PR_SetSocketOption(
PRFileDesc *fd, const PRSocketOptionData *data);
/*
*********************************************************************
*
* File descriptor inheritance
*
*********************************************************************
*/
/*
************************************************************************
* FUNCTION: PR_SetFDInheritable
* DESCRIPTION:
* Set the inheritance attribute of a file descriptor.
*
* INPUTS:
* PRFileDesc *fd
* Points to a PRFileDesc object.
* PRBool inheritable
* If PR_TRUE, the file descriptor fd is set to be inheritable
* by a child process. If PR_FALSE, the file descriptor is set
* to be not inheritable by a child process.
* RETURN: PRStatus
* Upon successful completion, PR_SetFDInheritable returns PR_SUCCESS.
* Otherwise, it returns PR_FAILURE. Further failure information can
* be obtained by calling PR_GetError().
*************************************************************************
*/
PR_EXTERN(PRStatus) PR_SetFDInheritable(
PRFileDesc *fd,
PRBool inheritable);
/*
************************************************************************
* FUNCTION: PR_GetInheritedFD
* DESCRIPTION:
* Get an inherited file descriptor with the specified name.
*
* INPUTS:
* const char *name
* The name of the inherited file descriptor.
* RETURN: PRFileDesc *
* Upon successful completion, PR_GetInheritedFD returns the
* inherited file descriptor with the specified name. Otherwise,
* it returns NULL. Further failure information can be obtained
* by calling PR_GetError().
*************************************************************************
*/
PR_EXTERN(PRFileDesc *) PR_GetInheritedFD(const char *name);
/*
*********************************************************************
*

View File

@ -921,9 +921,6 @@ extern PRThread* _PR_MD_CREATE_USER_THREAD(
#define _PR_MD_CREATE_USER_THREAD _MD_CREATE_USER_THREAD
#endif
extern void _PR_MD_INIT_PRIMORDIAL_THREAD(PRThread *thread);
#define _PR_MD_INIT_PRIMORDIAL_THREAD _MD_INIT_PRIMORDIAL_THREAD
extern PRStatus _PR_MD_CREATE_THREAD(
PRThread *thread,
void (*start) (void *),
@ -966,6 +963,9 @@ extern PRInt32 _PR_MD_CLOSE_DIR(_MDDir *md);
#define _PR_MD_CLOSE_DIR _MD_CLOSE_DIR
/* I/O related */
extern void _PR_MD_INIT_FILEDESC(PRFileDesc *fd);
#define _PR_MD_INIT_FILEDESC _MD_INIT_FILEDESC
extern void _PR_MD_MAKE_NONBLOCK(PRFileDesc *fd);
#define _PR_MD_MAKE_NONBLOCK _MD_MAKE_NONBLOCK
@ -1123,6 +1123,9 @@ extern PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds,
PRIntervalTime timeout);
#define _PR_MD_PR_POLL _MD_PR_POLL
extern PRStatus _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable);
#define _PR_MD_SET_FD_INHERITABLE _MD_SET_FD_INHERITABLE
#define _PR_PROCESS_TIMEOUT_INTERRUPT_ERRORS(me) \
if (_PR_PENDING_INTERRUPT(me)) { \
@ -1414,6 +1417,9 @@ struct PRProcessAttr {
PRFileDesc *stdoutFd;
PRFileDesc *stderrFd;
char *currentDirectory;
char *fdInheritBuffer;
PRSize fdInheritBufferSize;
PRSize fdInheritBufferUsed;
};
struct PRProcess {
@ -1431,6 +1437,7 @@ struct PRFileMap {
struct PRFilePrivate {
PRInt32 state;
PRBool nonblocking;
PRBool inheritable;
PRFileDesc *next;
PRIntn lockCount;
_MDFileDesc md;

View File

@ -57,6 +57,12 @@ PR_EXTERN(PRStatus) PR_ProcessAttrSetCurrentDirectory(
const char *dir
);
PR_EXTERN(PRStatus) PR_ProcessAttrSetInheritableFD(
PRProcessAttr *attr,
PRFileDesc *fd,
const char *name
);
/*
** Create a new process
**

View File

@ -249,13 +249,13 @@ PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode)
PRInt32 osfd;
PRFileDesc *fd = 0;
if (!_pr_initialized) _PR_ImplicitInitialization();
if (!_pr_initialized) _PR_ImplicitInitialization();
/* Map pr open flags and mode to os specific flags */
osfd = _PR_MD_OPEN(name, flags, mode);
if (osfd != -1) {
fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
if (!fd) {
(void) _PR_MD_CLOSE_FILE(osfd);
}

View File

@ -90,6 +90,7 @@ PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(
fd->methods = methods;
fd->secret->state = _PR_FILEDESC_OPEN;
fd->secret->md.osfd = osfd;
_PR_MD_INIT_FILEDESC(fd);
} else {
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
}
@ -110,3 +111,32 @@ PR_IMPLEMENT(PRInt32) PR_Poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeo
{
return(_PR_MD_PR_POLL(pds, npds, timeout));
}
/*
** Set the inheritance attribute of a file descriptor.
*/
PR_IMPLEMENT(PRStatus) PR_SetFDInheritable(
PRFileDesc *fd,
PRBool inheritable)
{
#if defined(XP_UNIX) || defined(WIN32)
/*
* Only a non-layered, NSPR file descriptor can be inherited
* by a child process.
*/
if (fd->identity != PR_NSPR_IO_LAYER) {
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
return PR_FAILURE;
}
if (fd->secret->inheritable != inheritable) {
if (_PR_MD_SET_FD_INHERITABLE(fd, inheritable) == PR_FAILURE) {
return PR_FAILURE;
}
fd->secret->inheritable = inheritable;
}
return PR_SUCCESS;
#else
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
return PR_FAILURE;
#endif
}

View File

@ -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);

View File

@ -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;

View File

@ -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++) {

View File

@ -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

View File

@ -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++;
}
qsort((void *) newEnvp, (size_t) numEnv, sizeof(char *), compare);
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;
}
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);
}

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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;
}

View File

@ -53,8 +53,8 @@
* arithmetic, ties are broken by the IEEE round-even rule. Otherwise
* ties are broken by biased rounding (add half and chop).
*
* Inspired loosely by William D. Clinger's paper "How to Read Floating
* Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
* Inspired loosely by William D. Clinger's paper "How to Read
* Floating-Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
*
* Modifications:
*
@ -1810,7 +1810,7 @@ quorem(Bigint *b, Bigint *S)
/* PR_dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
*
* Inspired by "How to Print Floating-Point Numbers Accurately" by
* Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
* Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
*
* Modifications:
* 1. Rather than iterating, we use a simple numeric overestimate

View File

@ -401,6 +401,7 @@ PR_IMPLEMENT(void)
PR_ResetProcessAttr(PRProcessAttr *attr)
{
PR_FREEIF(attr->currentDirectory);
PR_FREEIF(attr->fdInheritBuffer);
memset(attr, 0, sizeof(*attr));
}
@ -408,6 +409,7 @@ PR_IMPLEMENT(void)
PR_DestroyProcessAttr(PRProcessAttr *attr)
{
PR_FREEIF(attr->currentDirectory);
PR_FREEIF(attr->fdInheritBuffer);
PR_DELETE(attr);
}
@ -466,6 +468,121 @@ PR_ProcessAttrSetCurrentDirectory(
return PR_SUCCESS;
}
PR_IMPLEMENT(PRStatus)
PR_ProcessAttrSetInheritableFD(
PRProcessAttr *attr,
PRFileDesc *fd,
const char *name)
{
/* We malloc the fd inherit buffer in multiples of this number. */
#define FD_INHERIT_BUFFER_INCR 128
/* The length of "NSPR_INHERIT_FDS=" */
#define NSPR_INHERIT_FDS_STRLEN 17
/* The length of osfd (PRInt32) printed in hexadecimal with 0x prefix */
#define OSFD_STRLEN 10
int newSize;
int remainder;
char *newBuffer;
int nwritten;
char *cur;
int freeSize;
if (fd->identity != PR_NSPR_IO_LAYER) {
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
return PR_FAILURE;
}
if (!fd->secret->inheritable) {
PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0);
return PR_FAILURE;
}
/*
* We also need to account for the : separators and the
* terminating null byte.
*/
if (NULL == attr->fdInheritBuffer) {
/* The first time, we print "NSPR_INHERIT_FDS=<name>:<val>" */
newSize = NSPR_INHERIT_FDS_STRLEN + strlen(name)
+ OSFD_STRLEN + 1 + 1;
} else {
/* At other times, we print ":<name>:<val>" */
newSize = attr->fdInheritBufferUsed + strlen(name)
+ OSFD_STRLEN + 2 + 1;
}
if (newSize > attr->fdInheritBufferSize) {
/* Make newSize a multiple of FD_INHERIT_BUFFER_INCR */
remainder = newSize % FD_INHERIT_BUFFER_INCR;
if (remainder != 0) {
newSize += (FD_INHERIT_BUFFER_INCR - remainder);
}
if (NULL == attr->fdInheritBuffer) {
newBuffer = (char *) PR_MALLOC(newSize);
} else {
newBuffer = (char *) PR_REALLOC(attr->fdInheritBuffer, newSize);
}
if (NULL == newBuffer) {
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
return PR_FAILURE;
}
attr->fdInheritBuffer = newBuffer;
attr->fdInheritBufferSize = newSize;
}
cur = attr->fdInheritBuffer + attr->fdInheritBufferUsed;
freeSize = attr->fdInheritBufferSize - attr->fdInheritBufferUsed;
if (0 == attr->fdInheritBufferUsed) {
nwritten = PR_snprintf(cur, freeSize, "NSPR_INHERIT_FDS=%s:0x%lx",
name, fd->secret->md.osfd);
} else {
nwritten = PR_snprintf(cur, freeSize, ":%s:0x%lx",
name, fd->secret->md.osfd);
}
attr->fdInheritBufferUsed += nwritten;
return PR_SUCCESS;
}
PR_IMPLEMENT(PRFileDesc *) PR_GetInheritedFD(
const char *name)
{
PRFileDesc *fd;
const char *envVar;
const char *ptr;
int len = strlen(name);
PRInt32 osfd;
int nColons;
envVar = PR_GetEnv("NSPR_INHERIT_FDS");
if (NULL == envVar || '\0' == envVar[0]) {
PR_SetError(PR_UNKNOWN_ERROR, 0);
return NULL;
}
ptr = envVar;
while (1) {
if ((ptr[len] == ':') && (strncmp(ptr, name, len) == 0)) {
ptr += len + 1;
PR_sscanf(ptr, "0x%lx", &osfd);
fd = PR_ImportFile(osfd);
return fd;
}
/* Skip two colons */
nColons = 0;
while (*ptr) {
if (*ptr == ':') {
if (++nColons == 2) {
break;
}
}
ptr++;
}
if (*ptr == '\0') {
PR_SetError(PR_UNKNOWN_ERROR, 0);
return NULL;
}
ptr++;
}
return NULL;
}
PR_IMPLEMENT(PRProcess*) PR_CreateProcess(
const char *path,
char *const *argv,

View File

@ -2545,6 +2545,9 @@ static PRFileDesc *pt_SetMethods(PRIntn osfd, PRDescType type)
{
fd->secret->md.osfd = osfd;
fd->secret->state = _PR_FILEDESC_OPEN;
/* By default, a Unix fd is not closed on exec. */
PR_ASSERT(0 == fcntl(osfd, F_GETFD, 0));
fd->secret->inheritable = PR_TRUE;
switch (type)
{
case PR_DESC_FILE:
@ -2609,6 +2612,9 @@ PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(
fcntl(osfd, F_SETFL, flags | _PR_FCNTL_FLAGS);
}
fd->secret->state = _PR_FILEDESC_OPEN;
/* By default, a Unix fd is not closed on exec. */
PR_ASSERT(0 == fcntl(osfd, F_GETFD, 0));
fd->secret->inheritable = PR_TRUE;
return fd;
failed:
@ -3241,6 +3247,34 @@ PR_IMPLEMENT(PRStatus) PR_CreatePipe(
return PR_SUCCESS;
}
/*
** Set the inheritance attribute of a file descriptor.
*/
PR_IMPLEMENT(PRStatus) PR_SetFDInheritable(
PRFileDesc *fd,
PRBool inheritable)
{
/*
* Only a non-layered, NSPR file descriptor can be inherited
* by a child process.
*/
if (fd->identity != PR_NSPR_IO_LAYER)
{
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
return PR_FAILURE;
}
if (fd->secret->inheritable != inheritable)
{
if (fcntl(fd->secret->md.osfd, F_SETFD,
inheritable ? 0 : FD_CLOEXEC) == -1)
{
return PR_FAILURE;
}
fd->secret->inheritable = inheritable;
}
return PR_SUCCESS;
}
/*****************************************************************************/
/***************************** I/O friends methods ***************************/
/*****************************************************************************/

View File

@ -368,8 +368,6 @@ void _PR_NativeRunThread(void *arg)
while(1) {
thread->state = _PR_RUNNING;
if ( !_PR_IS_NATIVE_THREAD(thread)) _PR_MD_SET_INTSOFF(0);
/*
* Add to list of active threads
*/

View File

@ -218,7 +218,7 @@ static void OneShot(void *arg)
PRFileDesc *pair[2];
PRIntn test = (PRIntn)arg;
for (test = 0; test < 11; ++test) {
for (test = 0; test < 12; ++test) {
switch (test)
{
@ -295,6 +295,12 @@ static void OneShot(void *arg)
DPRINTF((output,"Thread[0x%x] called PR_SetConcurrency\n",
PR_GetCurrentThread()));
break;
case 11:
PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_HIGH);
DPRINTF((output,"Thread[0x%x] called PR_SetThreadPriority\n",
PR_GetCurrentThread()));
break;
default:
break;
@ -305,7 +311,6 @@ static void OneShot(void *arg)
PRIntn main(PRIntn argc, char **argv)
{
PRStatus rv;
PRIntn test_number;
PRInt32 thread_cnt = DEFAULT_THREAD_COUNT;
PLOptStatus os;
PLOptState *opt = PL_CreateOptState(argc, argv, "dt:");