📄 prinit.c
字号:
_PR_CleanupCallOnce(); _PR_ShutdownLinker(); /* Release the primordial thread's private data, etc. */ _PR_CleanupThread(me); _PR_MD_STOP_INTERRUPTS(); PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: clean up before destroying thread")); _PR_LogCleanup(); /* * This part should look like the end of _PR_NativeRunThread * and _PR_UserRunThread. */ if (_PR_IS_NATIVE_THREAD(me)) { _PR_MD_EXIT_THREAD(me); _PR_NativeDestroyThread(me); } else { _PR_UserDestroyThread(me); PR_DELETE(me->stack); PR_DELETE(me); } /* * XXX: We are freeing the heap memory here so that Purify won't * complain, but we should also free other kinds of resources * that are allocated by the _PR_InitXXX() functions. * Ideally, for each _PR_InitXXX(), there should be a corresponding * _PR_XXXCleanup() that we can call here. */ _PR_CleanupNet(); _PR_CleanupIO();#ifdef WINNT _PR_CleanupCPUs();#endif _PR_CleanupThreads(); PR_DestroyLock(_pr_sleeplock); _pr_sleeplock = NULL; _PR_CleanupLayerCache(); _PR_CleanupEnv(); _PR_CleanupStacks(); _PR_CleanupBeforeExit(); _pr_initialized = PR_FALSE; return PR_SUCCESS; } return PR_FAILURE;}#endif /* defined(_PR_PTHREADS) *//* *------------------------------------------------------------------------ * PR_ProcessExit -- * * Cause an immediate, nongraceful, forced termination of the process. * It takes a PRIntn argument, which is the exit status code of the * process. * * See also: PR_Cleanup() * *------------------------------------------------------------------------ */#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS) /* see ptthread.c */#elsePR_IMPLEMENT(void) PR_ProcessExit(PRIntn status){ _PR_MD_EXIT(status);}#endif /* defined(_PR_PTHREADS) */PR_IMPLEMENT(PRProcessAttr *)PR_NewProcessAttr(void){ PRProcessAttr *attr; attr = PR_NEWZAP(PRProcessAttr); if (!attr) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); } return attr;}PR_IMPLEMENT(void)PR_ResetProcessAttr(PRProcessAttr *attr){ PR_FREEIF(attr->currentDirectory); PR_FREEIF(attr->fdInheritBuffer); memset(attr, 0, sizeof(*attr));}PR_IMPLEMENT(void)PR_DestroyProcessAttr(PRProcessAttr *attr){ PR_FREEIF(attr->currentDirectory); PR_FREEIF(attr->fdInheritBuffer); PR_DELETE(attr);}PR_IMPLEMENT(void)PR_ProcessAttrSetStdioRedirect( PRProcessAttr *attr, PRSpecialFD stdioFd, PRFileDesc *redirectFd){ switch (stdioFd) { case PR_StandardInput: attr->stdinFd = redirectFd; break; case PR_StandardOutput: attr->stdoutFd = redirectFd; break; case PR_StandardError: attr->stderrFd = redirectFd; break; default: PR_ASSERT(0); }}/* * OBSOLETE */PR_IMPLEMENT(void)PR_SetStdioRedirect( PRProcessAttr *attr, PRSpecialFD stdioFd, PRFileDesc *redirectFd){#if defined(DEBUG) static PRBool warn = PR_TRUE; if (warn) { warn = _PR_Obsolete("PR_SetStdioRedirect()", "PR_ProcessAttrSetStdioRedirect()"); }#endif PR_ProcessAttrSetStdioRedirect(attr, stdioFd, redirectFd);}PR_IMPLEMENT(PRStatus)PR_ProcessAttrSetCurrentDirectory( PRProcessAttr *attr, const char *dir){ PR_FREEIF(attr->currentDirectory); attr->currentDirectory = (char *) PR_MALLOC(strlen(dir) + 1); if (!attr->currentDirectory) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); return PR_FAILURE; } strcpy(attr->currentDirectory, dir); 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 /* The length of fd type (PRDescType) printed in decimal */#define FD_TYPE_STRLEN 1 PRSize 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_TRI_UNKNOWN) { _PR_MD_QUERY_FD_INHERITABLE(fd); } if (fd->secret->inheritable != _PR_TRI_TRUE) { 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>:<type>:<val>" */ newSize = NSPR_INHERIT_FDS_STRLEN + strlen(name) + FD_TYPE_STRLEN + OSFD_STRLEN + 2 + 1; } else { /* At other times, we print ":<name>:<type>:<val>" */ newSize = attr->fdInheritBufferUsed + strlen(name) + FD_TYPE_STRLEN + OSFD_STRLEN + 3 + 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:%d:0x%lx", name, (PRIntn)fd->methods->file_type, fd->secret->md.osfd); } else { nwritten = PR_snprintf(cur, freeSize, ":%s:%d:0x%lx", name, (PRIntn)fd->methods->file_type, 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; PRIntn fileType; 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, "%d:0x%lx", &fileType, &osfd); switch ((PRDescType)fileType) { case PR_DESC_FILE: fd = PR_ImportFile(osfd); break; case PR_DESC_PIPE: fd = PR_ImportPipe(osfd); break; case PR_DESC_SOCKET_TCP: fd = PR_ImportTCPSocket(osfd); break; case PR_DESC_SOCKET_UDP: fd = PR_ImportUDPSocket(osfd); break; default: PR_ASSERT(0); PR_SetError(PR_UNKNOWN_ERROR, 0); fd = NULL; break; } if (fd) { /* * An inherited FD is inheritable by default. * The child process needs to call PR_SetFDInheritable * to make it non-inheritable if so desired. */ fd->secret->inheritable = _PR_TRI_TRUE; } return fd; } /* Skip three colons */ nColons = 0; while (*ptr) { if (*ptr == ':') { if (++nColons == 3) { break; } } ptr++; } if (*ptr == '\0') { PR_SetError(PR_UNKNOWN_ERROR, 0); return NULL; } ptr++; }}PR_IMPLEMENT(PRProcess*) PR_CreateProcess( const char *path, char *const *argv, char *const *envp, const PRProcessAttr *attr){ return _PR_MD_CREATE_PROCESS(path, argv, envp, attr);} /* PR_CreateProcess */PR_IMPLEMENT(PRStatus) PR_CreateProcessDetached( const char *path, char *const *argv, char *const *envp, const PRProcessAttr *attr){ PRProcess *process; PRStatus rv; process = PR_CreateProcess(path, argv, envp, attr); if (NULL == process) { return PR_FAILURE; } rv = PR_DetachProcess(process); PR_ASSERT(PR_SUCCESS == rv); if (rv == PR_FAILURE) { PR_DELETE(process); return PR_FAILURE; } return PR_SUCCESS;}PR_IMPLEMENT(PRStatus) PR_DetachProcess(PRProcess *process){ return _PR_MD_DETACH_PROCESS(process);}PR_IMPLEMENT(PRStatus) PR_WaitProcess(PRProcess *process, PRInt32 *exitCode){ return _PR_MD_WAIT_PROCESS(process, exitCode);} /* PR_WaitProcess */PR_IMPLEMENT(PRStatus) PR_KillProcess(PRProcess *process){ return _PR_MD_KILL_PROCESS(process);}/* ******************************************************************** * * Module initialization * ******************************************************************** */static struct { PRLock *ml; PRCondVar *cv;} mod_init;static void _PR_InitCallOnce(void) { mod_init.ml = PR_NewLock(); PR_ASSERT(NULL != mod_init.ml); mod_init.cv = PR_NewCondVar(mod_init.ml); PR_ASSERT(NULL != mod_init.cv);}void _PR_CleanupCallOnce(){ PR_DestroyLock(mod_init.ml); mod_init.ml = NULL; PR_DestroyCondVar(mod_init.cv); mod_init.cv = NULL;}PR_IMPLEMENT(PRStatus) PR_CallOnce( PRCallOnceType *once, PRCallOnceFN func){ if (!_pr_initialized) _PR_ImplicitInitialization(); if (!once->initialized) { if (PR_AtomicSet(&once->inProgress, 1) == 0) { once->status = (*func)(); PR_Lock(mod_init.ml); once->initialized = 1; PR_NotifyAllCondVar(mod_init.cv); PR_Unlock(mod_init.ml); } else { PR_Lock(mod_init.ml); while (!once->initialized) { PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT); } PR_Unlock(mod_init.ml); } } return once->status;}PRBool _PR_Obsolete(const char *obsolete, const char *preferred){#if defined(DEBUG)#ifndef XP_MAC PR_fprintf( PR_STDERR, "'%s' is obsolete. Use '%s' instead.\n", obsolete, (NULL == preferred) ? "something else" : preferred);#else#pragma unused (obsolete, preferred)#endif#endif return PR_FALSE;} /* _PR_Obsolete *//* prinit.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -