Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
prinit.c File Reference
#include "primpl.h"
#include <ctype.h>
#include <string.h>

Go to the source code of this file.

Defines

#define FD_INHERIT_BUFFER_INCR   128
#define NSPR_INHERIT_FDS_STRLEN   17
#define OSFD_STRLEN   10
#define FD_TYPE_STRLEN   1

Functions

static void _PR_InitCallOnce (void)
 PR_IMPLEMENT (PRBool)
PRStatus _pr_init_ipv6 (void)
static void _PR_InitStuff (void)
void _PR_ImplicitInitialization (void)
 PR_IMPLEMENT (void)
 PR_IMPLEMENT (PRIntn)
static void _PR_CleanupBeforeExit (void)
 PR_IMPLEMENT (PRStatus)
 PR_NewProcessAttr (void)
 PR_ResetProcessAttr (PRProcessAttr *attr)
 PR_DestroyProcessAttr (PRProcessAttr *attr)
 PR_ProcessAttrSetStdioRedirect (PRProcessAttr *attr, PRSpecialFD stdioFd, PRFileDesc *redirectFd)
 PR_SetStdioRedirect (PRProcessAttr *attr, PRSpecialFD stdioFd, PRFileDesc *redirectFd)
 PR_ProcessAttrSetCurrentDirectory (PRProcessAttr *attr, const char *dir)
 PR_ProcessAttrSetInheritableFD (PRProcessAttr *attr, PRFileDesc *fd, const char *name)
 PR_IMPLEMENT (PRFileDesc *)
 PR_IMPLEMENT (PRProcess *)
void _PR_CleanupCallOnce ()
PRBool _PR_Obsolete (const char *obsolete, const char *preferred)

Variables

PRLogModuleInfo_pr_clock_lm
PRLogModuleInfo_pr_cmon_lm
PRLogModuleInfo_pr_io_lm
PRLogModuleInfo_pr_cvar_lm
PRLogModuleInfo_pr_mon_lm
PRLogModuleInfo_pr_linker_lm
PRLogModuleInfo_pr_sched_lm
PRLogModuleInfo_pr_thread_lm
PRLogModuleInfo_pr_gc_lm
PRLogModuleInfo_pr_shm_lm
PRLogModuleInfo_pr_shma_lm
PRFileDesc_pr_stdin
PRFileDesc_pr_stdout
PRFileDesc_pr_stderr
PRCList _pr_active_local_threadQ
PRCList _pr_active_global_threadQ
_MDLock _pr_cpuLock
PRCList _pr_cpuQ = PR_INIT_STATIC_CLIST(&_pr_cpuQ)
PRUint32 _pr_utid
PRInt32 _pr_userActive
PRInt32 _pr_systemActive
PRUintn _pr_maxPTDs
PRLock_pr_terminationCVLock
PRLock_pr_sleeplock
PRBool _pr_initialized = PR_FALSE
PRInt32 _native_threads_only = 0
struct {
PRLockml
PRCondVarcv
mod_init

Define Documentation

#define OSFD_STRLEN   10

Function Documentation

static void _PR_CleanupBeforeExit ( void  ) [static]

Definition at line 345 of file prinit.c.

{
/* 
Do not make any calls here other than to destroy resources.  For example,
do not make any calls that eventually may end up in PR_Lock.  Because the
thread is destroyed, can not access current thread any more.
*/
    _PR_CleanupTPD();
    if (_pr_terminationCVLock)
    /*
     * In light of the comment above, this looks real suspicious.
     * I'd go so far as to say it's just a problem waiting to happen.
     */
        PR_DestroyLock(_pr_terminationCVLock);

    _PR_MD_CLEANUP_BEFORE_EXIT();
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 795 of file prinit.c.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 257 of file prinit.c.

{
       _PR_InitStuff();

    /* Enable interrupts */
#if !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY)
    _PR_MD_START_INTERRUPTS();
#endif

}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 309 of file pripv6.c.

{
    const PRIOMethods *stubMethods;

#if defined(_PR_INET6_PROBE)
    _pr_ipv6_is_present = _pr_probe_ipv6_presence();
    if (PR_TRUE == _pr_ipv6_is_present)
        return PR_SUCCESS;
#endif

    _pr_ipv6_to_ipv4_id = PR_GetUniqueIdentity("Ipv6_to_Ipv4 layer");
    PR_ASSERT(PR_INVALID_IO_LAYER != _pr_ipv6_to_ipv4_id);

       stubMethods = PR_GetDefaultIOMethods();

       ipv6_to_v4_tcpMethods = *stubMethods;  /* first get the entire batch */
       /* then override the ones we care about */
       ipv6_to_v4_tcpMethods.connect = Ipv6ToIpv4SocketConnect;
       ipv6_to_v4_tcpMethods.bind = Ipv6ToIpv4SocketBind;
       ipv6_to_v4_tcpMethods.accept = Ipv6ToIpv4SocketAccept;
       ipv6_to_v4_tcpMethods.acceptread = Ipv6ToIpv4SocketAcceptRead;
       ipv6_to_v4_tcpMethods.getsockname = Ipv6ToIpv4SocketGetName;
       ipv6_to_v4_tcpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName;
/*
       ipv6_to_v4_tcpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption;
       ipv6_to_v4_tcpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption;
*/
       ipv6_to_v4_udpMethods = *stubMethods;  /* first get the entire batch */
       /* then override the ones we care about */
       ipv6_to_v4_udpMethods.connect = Ipv6ToIpv4SocketConnect;
       ipv6_to_v4_udpMethods.bind = Ipv6ToIpv4SocketBind;
       ipv6_to_v4_udpMethods.sendto = Ipv6ToIpv4SocketSendTo;
       ipv6_to_v4_udpMethods.recvfrom = Ipv6ToIpv4SocketRecvFrom;
       ipv6_to_v4_udpMethods.getsockname = Ipv6ToIpv4SocketGetName;
       ipv6_to_v4_udpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName;
/*
       ipv6_to_v4_udpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption;
       ipv6_to_v4_udpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption;
*/
       return PR_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void _PR_InitCallOnce ( void  ) [static]

Definition at line 788 of file prinit.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void _PR_InitStuff ( void  ) [static]

Definition at line 170 of file prinit.c.

{

    if (_pr_initialized) return;
    _pr_initialized = PR_TRUE;
#ifdef _PR_ZONE_ALLOCATOR
    _PR_InitZones();
#endif
#ifdef WINNT
    _pr_SetNativeThreadsOnlyMode();
#endif


    (void) PR_GetPageSize();

       _pr_clock_lm = PR_NewLogModule("clock");
       _pr_cmon_lm = PR_NewLogModule("cmon");
       _pr_io_lm = PR_NewLogModule("io");
       _pr_mon_lm = PR_NewLogModule("mon");
       _pr_linker_lm = PR_NewLogModule("linker");
       _pr_cvar_lm = PR_NewLogModule("cvar");
       _pr_sched_lm = PR_NewLogModule("sched");
       _pr_thread_lm = PR_NewLogModule("thread");
       _pr_gc_lm = PR_NewLogModule("gc");
       _pr_shm_lm = PR_NewLogModule("shm");
       _pr_shma_lm = PR_NewLogModule("shma");
      
    /* NOTE: These init's cannot depend on _PR_MD_CURRENT_THREAD() */ 
    _PR_MD_EARLY_INIT();

    _PR_InitLocks();
    _PR_InitAtomic();
    _PR_InitSegs();
    _PR_InitStacks();
       _PR_InitTPD();
    _PR_InitEnv();
    _PR_InitLayerCache();
    _PR_InitClock();

    _pr_sleeplock = PR_NewLock();
    PR_ASSERT(NULL != _pr_sleeplock);

#ifdef GC_LEAK_DETECTOR
    _PR_InitGarbageCollector();
#endif

    _PR_InitThreads(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    
#ifdef WIN16
       {
       PRInt32 top;   /* artificial top of stack, win16 */
    _pr_top_of_task_stack = (char *) &top;
       }
#endif    

#ifndef _PR_GLOBAL_THREADS_ONLY
       _PR_InitCPUs();
#endif

/*
 * XXX: call _PR_InitMem only on those platforms for which nspr implements
 *     malloc, for now.
 */
#ifdef _PR_OVERRIDE_MALLOC
    _PR_InitMem();
#endif

    _PR_InitCMon();
    _PR_InitIO();
    _PR_InitNet();
    _PR_InitLog();
    _PR_InitLinker();
    _PR_InitCallOnce();
    _PR_InitDtoa();
    _PR_InitTime();
    _PR_InitMW();
    _PR_InitRWLocks();

    nspr_InitializePRErrorTable();

#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
       _pr_init_ipv6();
#endif
       
    _PR_MD_FINAL_INIT();
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool _PR_Obsolete ( const char *  obsolete,
const char *  preferred 
)

Definition at line 852 of file prinit.c.

{
#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 */

Here is the caller graph for this function:

Definition at line 520 of file prinit.c.

Here is the caller graph for this function:

Definition at line 95 of file prinit.c.

{
    /*
    ** This is the secret handshake algorithm.
    **
    ** This release has a simple version compatibility
    ** check algorithm.  This release is not backward
    ** compatible with previous major releases.  It is
    ** not compatible with future major, minor, or
    ** patch releases.
    */
    int vmajor = 0, vminor = 0, vpatch = 0;
    const char *ptr = importedVersion;

    while (isdigit(*ptr)) {
        vmajor = 10 * vmajor + *ptr - '0';
        ptr++;
    }
    if (*ptr == '.') {
        ptr++;
        while (isdigit(*ptr)) {
            vminor = 10 * vminor + *ptr - '0';
            ptr++;
        }
        if (*ptr == '.') {
            ptr++;
            while (isdigit(*ptr)) {
                vpatch = 10 * vpatch + *ptr - '0';
                ptr++;
            }
        }
    }

    if (vmajor != PR_VMAJOR) {
        return PR_FALSE;
    }
    if (vmajor == PR_VMAJOR && vminor > PR_VMINOR) {
        return PR_FALSE;
    }
    if (vmajor == PR_VMAJOR && vminor == PR_VMINOR && vpatch > PR_VPATCH) {
        return PR_FALSE;
    }
    return PR_TRUE;
}  /* PR_VersionCheck */

Definition at line 268 of file prinit.c.

{
#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
       if (!_pr_initialized) {
              _PR_InitStuff();
       } else {
       _PR_MD_DISABLE_CLOCK_INTERRUPTS();
       }
#endif
}

Here is the call graph for this function:

PR_IMPLEMENT ( PRIntn  )

Definition at line 313 of file prinit.c.

{
#if defined(XP_MAC)
#pragma unused (maxPTDs)
#endif

    PRIntn rv;
    _PR_ImplicitInitialization();
    rv = prmain(argc, argv);
       PR_Cleanup();
    return rv;
}  /* PR_Initialize */

Here is the call graph for this function:

Definition at line 392 of file prinit.c.

{
    PRThread *me = PR_GetCurrentThread();
    PR_ASSERT((NULL != me) && (me->flags & _PR_PRIMORDIAL));
    if ((NULL != me) && (me->flags & _PR_PRIMORDIAL))
    {
        PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: shutting down NSPR"));

        /*
         * No more recycling of threads
         */
        _pr_recycleThreads = 0;

        /*
         * Wait for all other user (non-system/daemon) threads
         * to terminate.
         */
        PR_Lock(_pr_activeLock);
        while (_pr_userActive > _pr_primordialExitCount) {
            PR_WaitCondVar(_pr_primordialExitCVar, PR_INTERVAL_NO_TIMEOUT);
        }
        PR_Unlock(_pr_activeLock);

#ifdef IRIX
              _PR_MD_PRE_CLEANUP(me);
              /*
               * The primordial thread must now be running on the primordial cpu
               */
       PR_ASSERT((_PR_IS_NATIVE_THREAD(me)) || (me->cpu->id == 0));
#endif

        _PR_CleanupMW();
        _PR_CleanupTime();
        _PR_CleanupDtoa();
        _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;
}

Here is the call graph for this function:

Definition at line 660 of file prinit.c.

{
    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++;
    }
}

Here is the call graph for this function:

Definition at line 729 of file prinit.c.

{
    return _PR_MD_CREATE_PROCESS(path, argv, envp, attr);
}  /* PR_CreateProcess */

Here is the call graph for this function:

Definition at line 500 of file prinit.c.

{
    PRProcessAttr *attr;

    attr = PR_NEWZAP(PRProcessAttr);
    if (!attr) {
        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
    }
    return attr;
}

Here is the caller graph for this function:

Definition at line 568 of file prinit.c.

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

Here is the caller graph for this function:

PR_ProcessAttrSetInheritableFD ( PRProcessAttr attr,
PRFileDesc fd,
const char *  name 
)

Definition at line 583 of file prinit.c.

{
    /* 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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PR_ProcessAttrSetStdioRedirect ( PRProcessAttr attr,
PRSpecialFD  stdioFd,
PRFileDesc redirectFd 
)

Definition at line 528 of file prinit.c.

{
    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);
    }
}

Here is the caller graph for this function:

Definition at line 512 of file prinit.c.

{
    PR_FREEIF(attr->currentDirectory);
    PR_FREEIF(attr->fdInheritBuffer);
    memset(attr, 0, sizeof(*attr));
}

Here is the call graph for this function:

PR_SetStdioRedirect ( PRProcessAttr attr,
PRSpecialFD  stdioFd,
PRFileDesc redirectFd 
)

Definition at line 552 of file prinit.c.

{
#if defined(DEBUG)
    static PRBool warn = PR_TRUE;
    if (warn) {
        warn = _PR_Obsolete("PR_SetStdioRedirect()",
                "PR_ProcessAttrSetStdioRedirect()");
    }
#endif
    PR_ProcessAttrSetStdioRedirect(attr, stdioFd, redirectFd);
}

Here is the call graph for this function:


Variable Documentation

Definition at line 146 of file prinit.c.

Initial value:

Definition at line 62 of file prinit.c.

Initial value:

Definition at line 60 of file prinit.c.

Definition at line 42 of file prinit.c.

Definition at line 43 of file prinit.c.

Definition at line 65 of file prinit.c.

Definition at line 66 of file prinit.c.

Definition at line 45 of file prinit.c.

Definition at line 50 of file prinit.c.

Definition at line 92 of file prinit.c.

Definition at line 44 of file prinit.c.

Definition at line 47 of file prinit.c.

PRUintn _pr_maxPTDs

Definition at line 72 of file prinit.c.

Definition at line 46 of file prinit.c.

Definition at line 48 of file prinit.c.

Definition at line 51 of file prinit.c.

Definition at line 52 of file prinit.c.

Definition at line 88 of file prinit.c.

Definition at line 56 of file prinit.c.

Definition at line 54 of file prinit.c.

Definition at line 55 of file prinit.c.

Definition at line 71 of file prinit.c.

Definition at line 84 of file prinit.c.

Definition at line 49 of file prinit.c.

Definition at line 70 of file prinit.c.

Definition at line 68 of file prinit.c.

struct { ... } mod_init [static]