mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-01 13:57:32 +00:00
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:
parent
cc72577fd7
commit
c9f4f25104
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 *),
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 *, ...);
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
*********************************************************************
|
||||
*
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
**
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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++) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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 ***************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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:");
|
||||
|
Loading…
x
Reference in New Issue
Block a user