VirtualBox

Changeset 3368 in vbox for trunk/src/libs


Ignore:
Timestamp:
Jul 3, 2007 12:23:27 AM (17 years ago)
Author:
vboxsync
Message:

NSPR/OS/2:

  • Implemented correct import of named inherited file objects in child processes.
  • Implemented real function of PR_CreateProcessDetached().
  • Fixed: File handles and sockets are now non-inheritable by child processes by default.
Location:
trunk/src/libs/xpcom18a4/nsprpub/pr
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/xpcom18a4/nsprpub/pr/include/md/_os2.h

    r3149 r3368  
    432432struct PRProcessAttr;
    433433
     434extern struct PRProcess * _PR_CreateOS2ProcessEx(
     435    const char *path,
     436    char *const *argv,
     437    char *const *envp,
     438    const struct PRProcessAttr *attr,
     439    PRBool detached
     440);
     441
    434442#define _MD_CREATE_PROCESS _PR_CreateOS2Process
    435443extern struct PRProcess * _PR_CreateOS2Process(
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/md/os2/os2io.c

    r1 r3368  
    155155
    156156    if (osflags & PR_SYNC) access |= OPEN_FLAGS_WRITE_THROUGH;
     157
     158    /* we don't want to let children inherit file handles by default */
     159    access |= OPEN_FLAGS_NOINHERIT;
    157160
    158161    if (osflags & PR_RDONLY)
     
    587590_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info)
    588591{
    589    /* For once, the VAC compiler/library did a nice thing.
    590     * The file handle used by the C runtime is the same one
    591     * returned by the OS when you call DosOpen().  This means
    592     * that you can take an OS HFILE and use it with C file
    593     * functions.  The only caveat is that you have to call
    594     * _setmode() first to initialize some junk.  This is
    595     * immensely useful because I did not have a clue how to
    596     * implement this function otherwise.  The windows folks
    597     * took the source from the Microsoft C library source, but
    598     * IBM wasn't kind enough to ship the source with VAC.
    599     * On second thought, the needed function could probably
    600     * be gotten from the OS/2 GNU library source, but the
    601     * point is now moot.
    602     */
    603    struct stat hinfo;
     592    /* For once, the VAC compiler/library did a nice thing.
     593     * The file handle used by the C runtime is the same one
     594     * returned by the OS when you call DosOpen().  This means
     595     * that you can take an OS HFILE and use it with C file
     596     * functions.  The only caveat is that you have to call
     597     * _setmode() first to initialize some junk.  This is
     598     * immensely useful because I did not have a clue how to
     599     * implement this function otherwise.  The windows folks
     600     * took the source from the Microsoft C library source, but
     601     * IBM wasn't kind enough to ship the source with VAC.
     602     * On second thought, the needed function could probably
     603     * be gotten from the OS/2 GNU library source, but the
     604     * point is now moot.
     605     */
     606    struct stat hinfo;
    604607    PRInt64 s, s2us;
    605608
     
    660663_PR_MD_ACCESS(const char *name, PRAccessHow how)
    661664{
    662   PRInt32 rv;
     665    PRInt32 rv;
    663666    switch (how) {
    664667      case PR_ACCESS_WRITE_OK:
     
    683686_PR_MD_MKDIR(const char *name, PRIntn mode)
    684687{
    685    PRInt32 rc;
     688    PRInt32 rc;
    686689    /* XXXMB - how to translate the "mode"??? */
    687690    if ((rc = DosCreateDir((char *)name, NULL))== NO_ERROR) {
     
    696699_PR_MD_RMDIR(const char *name)
    697700{
    698    PRInt32 rc;
     701    PRInt32 rc;
    699702    if ( (rc = DosDeleteDir((char *)name)) == NO_ERROR) {
    700703        return 0;
     
    709712{
    710713        PRInt32   rv;
    711    FILELOCK lock, unlock;
    712 
    713    lock.lOffset = 0;
    714    lock.lRange = 0xffffffff;
    715    unlock.lOffset = 0;
    716    unlock.lRange = 0;
     714    FILELOCK lock, unlock;
     715
     716    lock.lOffset = 0;
     717    lock.lRange = 0xffffffff;
     718    unlock.lOffset = 0;
     719    unlock.lRange = 0;
    717720
    718721        /*
     
    746749{
    747750        PRInt32   rv;
    748    FILELOCK lock, unlock;
    749 
    750    lock.lOffset = 0;
    751    lock.lRange = 0;
    752    unlock.lOffset = 0;
    753    unlock.lRange = 0xffffffff;
     751    FILELOCK lock, unlock;
     752
     753    lock.lOffset = 0;
     754    lock.lRange = 0;
     755    unlock.lOffset = 0;
     756    unlock.lRange = 0xffffffff;
    754757   
    755    rv = DosSetFileLocks( (HFILE) f,
     758    rv = DosSetFileLocks( (HFILE) f,
    756759                          &unlock, &lock,
    757760                          0, 0);
     
    778781            rc = DosQueryFHState((HFILE)fd->secret->md.osfd, &flags);
    779782            if (rc != NO_ERROR) {
    780                 PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
     783                PR_SetError(PR_UNKNOWN_ERROR, rc);
    781784                return PR_FAILURE;
    782785            }
     
    791794            rc = DosSetFHState((HFILE)fd->secret->md.osfd, flags);
    792795            if (rc != NO_ERROR) {
     796                PR_SetError(PR_UNKNOWN_ERROR, rc);
     797                return PR_FAILURE;
     798            }
     799            break;
     800
     801        case PR_DESC_LAYERED:
     802            /* XXX what to do here? */
     803            PR_SetError(PR_UNKNOWN_ERROR, 87 /*ERROR_INVALID_PARAMETER*/);
     804            return PR_FAILURE;
     805
     806        case PR_DESC_SOCKET_TCP:
     807        case PR_DESC_SOCKET_UDP:
     808        {
     809#ifdef XP_OS2_EMX
     810            int rv = fcntl(fd->secret->md.osfd, F_SETFD, inheritable ? 0 : FD_CLOEXEC);
     811            if (-1 == rv) {
    793812                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
    794813                return PR_FAILURE;
    795814            }
     815#else
     816            /* In VAC, socket() FDs are global. */
     817#endif
    796818            break;
     819        }
     820    }
     821
     822    return PR_SUCCESS;
     823}
     824
     825void
     826_PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported)
     827{
     828    if (imported) {
     829        /* for imported handles, we'll determine the inheritance state later
     830         * in _PR_MD_QUERY_FD_INHERITABLE */
     831        fd->secret->inheritable = _PR_TRI_UNKNOWN;
     832    } else {
     833        switch (fd->methods->file_type)
     834        {
     835            case PR_DESC_PIPE:
     836                /* On OS/2, pipe handles created by NPSR (PR_CreatePipe) are
     837                 * inheritable by default */
     838                fd->secret->inheritable = _PR_TRI_TRUE;
     839                break;
     840            case PR_DESC_FILE:
     841                /* On OS/2, file handles created by NPSR (_MD_OPEN) are
     842                 * made non-inheritable by default */
     843                fd->secret->inheritable = _PR_TRI_FALSE;
     844                break;
     845
     846            case PR_DESC_LAYERED:
     847                /* XXX what to do here? */
     848                break;
     849
     850            case PR_DESC_SOCKET_TCP:
     851            case PR_DESC_SOCKET_UDP:
     852#ifdef XP_OS2_EMX
     853                /* In EMX/GCC, sockets opened by NSPR (_PR_MD_SOCKET) are
     854                 * made non-inheritedable by default */
     855                fd->secret->inheritable = _PR_TRI_FALSE;
     856#else
     857                /* In VAC, socket() FDs are global. */
     858                fd->secret->inheritable = _PR_TRI_TRUE;
     859#endif
     860                break;
     861        }
     862    }
     863}
     864
     865void
     866_PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd)
     867{
     868    PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
     869
     870    switch (fd->methods->file_type)
     871    {
     872        case PR_DESC_PIPE:
     873        case PR_DESC_FILE:
     874        {
     875            ULONG flags;
     876            if (DosQueryFHState((HFILE)fd->secret->md.osfd, &flags) == 0) {
     877                if (flags & OPEN_FLAGS_NOINHERIT) {
     878                    fd->secret->inheritable = _PR_TRI_FALSE;
     879                } else {
     880                    fd->secret->inheritable = _PR_TRI_TRUE;
     881                }
     882            }
     883            break;
     884        }
    797885
    798886        case PR_DESC_LAYERED:
    799             /* what to do here? */
    800             PR_SetError(PR_UNKNOWN_ERROR, 87 /*ERROR_INVALID_PARAMETER*/);
    801             return PR_FAILURE;
     887            /* XXX what to do here? */
     888            break;
    802889
    803890        case PR_DESC_SOCKET_TCP:
    804891        case PR_DESC_SOCKET_UDP:
    805             /* These are global on OS/2. */
     892        {
     893#ifdef XP_OS2_EMX
     894            /* In EMX/GCC, socket() FDs are inherited by default. */
     895            int flags = fcntl(fd->secret->md.osfd, F_GETFD, 0);
     896            if (FD_CLOEXEC == flags) {
     897                fd->secret->inheritable = _PR_TRI_FALSE;
     898            } else {
     899                fd->secret->inheritable = _PR_TRI_TRUE;
     900            }
     901#else
     902            /* In VAC, socket() FDs are global. */
     903#endif
    806904            break;
    807     }
    808 
    809     return PR_SUCCESS;
    810 }
    811 
    812 void
    813 _PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported)
    814 {
    815     /* XXX this function needs to be implemented */
    816     fd->secret->inheritable = _PR_TRI_UNKNOWN;
    817 }
    818 
    819 void
    820 _PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd)
    821 {
    822     /* XXX this function needs to be reviewed */
    823     ULONG flags;
    824 
    825     PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
    826     if (DosQueryFHState((HFILE)fd->secret->md.osfd, &flags) == 0) {
    827         if (flags & OPEN_FLAGS_NOINHERIT) {
    828             fd->secret->inheritable = _PR_TRI_FALSE;
    829         } else {
    830             fd->secret->inheritable = _PR_TRI_TRUE;
    831905        }
    832906    }
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/md/os2/os2misc.c

    r1 r3368  
    234234}
    235235
    236 PRProcess * _PR_CreateOS2Process(
     236/*
     237 * On OS/2, you can only detach a new process -- you cannot make it detached
     238 * after it has been started. This is why _PR_CreateOS2ProcessEx() is
     239 * necessary. This function is called directly from PR_CreateProcessDetached().
     240 */
     241PRProcess * _PR_CreateOS2ProcessEx(
    237242    const char *path,
    238243    char *const *argv,
    239244    char *const *envp,
    240     const PRProcessAttr *attr)
     245    const PRProcessAttr *attr,
     246    PRBool detached)
    241247{
    242248    PRProcess *proc = NULL;
     
    245251    char *envBlock = NULL;
    246252   
    247     STARTDATA startData = {0};
    248253    APIRET    rc;
    249254    ULONG     ulAppType = 0;
     
    255260    char      pszObjectBuffer[CCHMAXPATH];
    256261    char     *pszFormatResult = NULL;
     262    char     *pszArg0 = NULL;
    257263
    258264    proc = PR_NEW(PRProcess);
     
    266272        goto errorExit;
    267273    }
    268    
    269     if (envp == NULL) {
    270         newEnvp = NULL;
    271     } else {
    272         int i;
    273         int numEnv = 0;
     274
     275    /* the 0th argument to the program (by convention, the program name, as
     276     * entered by user) */
     277    pszArg0 = argv[0];
     278
     279    /*
     280     * If attr->fdInheritBuffer is not NULL, we need to insert
     281     * it into the envp array, so envp cannot be NULL.
     282     */
     283    if ((envp == NULL) && attr && attr->fdInheritBuffer) {
     284        envp = environ;
     285    }
     286
     287    if (envp != NULL) {
     288        int idx;
     289        int numEnv;
     290        int newEnvpSize;
     291
     292        numEnv = 0;
    274293        while (envp[numEnv]) {
    275294            numEnv++;
    276295        }
    277         newEnvp = (char **) PR_MALLOC((numEnv+1) * sizeof(char *));
    278         for (i = 0; i <= numEnv; i++) {
    279             newEnvp[i] = envp[i];
    280         }
    281         qsort((void *) newEnvp, (size_t) numEnv, sizeof(char *), compare);
     296        newEnvpSize = numEnv + 1;  /* terminating null pointer */
     297        if (attr && attr->fdInheritBuffer) {
     298            newEnvpSize++;
     299        }
     300        newEnvp = (char **) PR_MALLOC(newEnvpSize * sizeof(char *));
     301        for (idx = 0; idx < numEnv; idx++) {
     302            newEnvp[idx] = envp[idx];
     303        }
     304        if (attr && attr->fdInheritBuffer) {
     305            newEnvp[idx++] = attr->fdInheritBuffer;
     306        }
     307        newEnvp[idx] = NULL;
     308        qsort((void *) newEnvp, (size_t) (newEnvpSize - 1),
     309                sizeof(char *), compare);
    282310    }
    283311    if (assembleEnvBlock(newEnvp, &envBlock) == -1) {
     
    285313        goto errorExit;
    286314    }
    287  
     315
    288316    if (attr) {
    289        PR_ASSERT(!"Not implemented");
     317        if (attr->stdinFd || attr->stdoutFd || attr->stderrFd)
     318            PR_ASSERT(!"Stdin/stdout redirection is not implemented");
     319        if (attr->currentDirectory)
     320            PR_ASSERT(!"Setting current directory is not implemented");
    290321    }
    291322
     
    300331                strcpy(pszFormatString, "/C %s %s");
    301332                strcpy(pszEXEName, pszComSpec);
     333                pszArg0 = pszEXEName;
    302334                ulAppType = FAPPTYP_WINDOWCOMPAT;
    303335             }
     
    309341       goto errorExit;
    310342    }
    311  
    312     if ((ulAppType & FAPPTYP_WINDOWAPI) == FAPPTYP_WINDOWAPI) {
    313         startData.SessionType = SSF_TYPE_PM;
    314     }
    315     else if (ulAppType & FAPPTYP_WINDOWCOMPAT) {
    316         startData.SessionType = SSF_TYPE_WINDOWABLEVIO;
     343
     344    if (detached) {
     345        /* we don't care about parent/child process type matching,
     346         * DosExecPgm() should complain if there is a mismatch. */
     347
     348        size_t cbArg0 = strlen(pszArg0);
     349        char *pszArgs = NULL;
     350
     351        if (pszEXEName[0]) {
     352            pszFormatResult = PR_MALLOC(cbArg0 + 1 +
     353                                        strlen(pszFormatString) +
     354                                        strlen(path) + strlen(cmdLine) + 1 + 1);
     355            if (!pszFormatResult) {
     356                PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
     357                goto errorExit;
     358            }
     359            pszArgs = pszFormatResult + cbArg0 + 1;
     360            sprintf(pszArgs, pszFormatString, path, cmdLine);
     361        } else {
     362            strcpy(pszEXEName, path);
     363            pszFormatResult = PR_MALLOC(cbArg0 + 1 +
     364                                        strlen(cmdLine) + 1 + 1);
     365            if (!pszFormatResult) {
     366                PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
     367                goto errorExit;
     368            }
     369            pszArgs = pszFormatResult + cbArg0 + 1;
     370            strcpy(pszArgs, cmdLine);
     371        }
     372
     373        strcpy(pszFormatResult, pszArg0);
     374        /* add final NULL */
     375        pszArgs[strlen(pszArgs) + 1] = '\0';
     376
     377        RESULTCODES res = {0};
     378        rc = DosExecPgm(pszObjectBuffer, CCHMAXPATH, EXEC_BACKGROUND,
     379                        pszFormatResult, envBlock, &res, pszEXEName);
     380
     381        if (rc != NO_ERROR) {
     382            PR_SetError(PR_UNKNOWN_ERROR, rc);
     383            goto errorExit;
     384        }
     385
     386        proc->md.pid = res.codeTerminate;
    317387    }
    318388    else {
    319         startData.SessionType = SSF_TYPE_DEFAULT;
    320     }
    321  
    322     if (ulAppType & (FAPPTYP_WINDOWSPROT31 | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL))
    323     {
    324         strcpy(pszEXEName, "WINOS2.COM");
    325         startData.SessionType = PROG_31_STDSEAMLESSVDM;
    326         strcpy(pszFormatString, "/3 %s %s");
    327     }
    328  
    329     startData.InheritOpt = SSF_INHERTOPT_SHELL;
    330  
    331     if (pszEXEName[0]) {
    332         pszFormatResult = PR_MALLOC(strlen(pszFormatString)+strlen(path)+strlen(cmdLine));
    333         sprintf(pszFormatResult, pszFormatString, path, cmdLine);
    334         startData.PgmInputs = pszFormatResult;
    335     } else {
    336         strcpy(pszEXEName, path);
    337         startData.PgmInputs = cmdLine;
    338     }
    339     startData.PgmName = pszEXEName;
    340  
    341     startData.Length = sizeof(startData);
    342     startData.Related = SSF_RELATED_INDEPENDENT;
    343     startData.ObjectBuffer = pszObjectBuffer;
    344     startData.ObjectBuffLen = CCHMAXPATH;
    345     startData.Environment = envBlock;
    346  
    347     rc = DosStartSession(&startData, &ulAppType, &pid);
    348 
    349     if ((rc != NO_ERROR) && (rc != ERROR_SMG_START_IN_BACKGROUND)) {
    350         PR_SetError(PR_UNKNOWN_ERROR, 0);
    351     }
    352  
    353     proc->md.pid = pid;
     389        STARTDATA startData = {0};
     390
     391        if ((ulAppType & FAPPTYP_WINDOWAPI) == FAPPTYP_WINDOWAPI) {
     392            startData.SessionType = SSF_TYPE_PM;
     393        }
     394        else if (ulAppType & FAPPTYP_WINDOWCOMPAT) {
     395            startData.SessionType = SSF_TYPE_WINDOWABLEVIO;
     396        }
     397        else {
     398            startData.SessionType = SSF_TYPE_DEFAULT;
     399        }
     400
     401        if (ulAppType & (FAPPTYP_WINDOWSPROT31 | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL))
     402        {
     403            strcpy(pszEXEName, "WINOS2.COM");
     404            startData.SessionType = PROG_31_STDSEAMLESSVDM;
     405            strcpy(pszFormatString, "/3 %s %s");
     406        }
     407
     408        startData.InheritOpt = SSF_INHERTOPT_PARENT;
     409
     410        if (pszEXEName[0]) {
     411            pszFormatResult = PR_MALLOC(strlen(pszFormatString)+strlen(path)+strlen(cmdLine));
     412            sprintf(pszFormatResult, pszFormatString, path, cmdLine);
     413            startData.PgmInputs = pszFormatResult;
     414        } else {
     415            strcpy(pszEXEName, path);
     416            startData.PgmInputs = cmdLine;
     417        }
     418        startData.PgmName = pszEXEName;
     419
     420        startData.Length = sizeof(startData);
     421        startData.Related = SSF_RELATED_INDEPENDENT;
     422        startData.ObjectBuffer = pszObjectBuffer;
     423        startData.ObjectBuffLen = CCHMAXPATH;
     424        startData.Environment = envBlock;
     425
     426        rc = DosStartSession(&startData, &ulAppType, &pid);
     427
     428        if ((rc != NO_ERROR) && (rc != ERROR_SMG_START_IN_BACKGROUND)) {
     429            PR_SetError(PR_UNKNOWN_ERROR, rc);
     430            goto errorExit;
     431        }
     432
     433        proc->md.pid = pid;
     434    }
    354435
    355436    if (pszFormatResult) {
    356437        PR_DELETE(pszFormatResult);
    357438    }
    358  
    359     PR_DELETE(cmdLine);
     439    if (cmdLine) {
     440        PR_DELETE(cmdLine);
     441    }
    360442    if (newEnvp) {
    361443        PR_DELETE(newEnvp);
     
    367449
    368450errorExit:
     451    if (pszFormatResult) {
     452        PR_DELETE(pszFormatResult);
     453    }
    369454    if (cmdLine) {
    370455        PR_DELETE(cmdLine);
     
    380465    }
    381466    return NULL;
    382 }  /* _PR_CreateOS2Process */
     467}  /* _PR_CreateOS2ProcessEx */
     468
     469PRProcess * _PR_CreateOS2Process(
     470    const char *path,
     471    char *const *argv,
     472    char *const *envp,
     473    const PRProcessAttr *attr)
     474{
     475    return _PR_CreateOS2ProcessEx(path, argv, envp, attr, PR_FALSE);
     476}
    383477
    384478PRStatus _PR_DetachOS2Process(PRProcess *process)
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/md/os2/os2sock.c

    r3149 r3368  
    8888        _PR_MD_MAP_SOCKET_ERROR(err);
    8989    }
     90
     91#ifdef XP_OS2_EMX
     92    /* Disable inheritance of socket FDs by default to avoid side effects */
     93    err = fcntl(osfd, F_SETFD, FD_CLOEXEC);
     94    if (-1 == err) {
     95        PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
     96        soclose(osfd);
     97        return -1;
     98    }
     99#endif
    90100
    91101    return(osfd);
  • trunk/src/libs/xpcom18a4/nsprpub/pr/src/misc/prinit.c

    r1 r3368  
    740740    const PRProcessAttr *attr)
    741741{
     742#ifdef XP_OS2
     743    PRProcess *process;
     744    process = _PR_CreateOS2ProcessEx(path, argv, envp, attr, PR_TRUE);
     745    if (NULL == process) {
     746        return PR_FAILURE;
     747    }
     748    return PR_SUCCESS;
     749#else
    742750    PRProcess *process;
    743751    PRStatus rv;
     
    745753    process = PR_CreateProcess(path, argv, envp, attr);
    746754    if (NULL == process) {
    747         return PR_FAILURE;
     755        return PR_FAILURE;
    748756    }
    749757    rv = PR_DetachProcess(process);
    750758    PR_ASSERT(PR_SUCCESS == rv);
    751759    if (rv == PR_FAILURE) {
    752         PR_DELETE(process);
    753         return PR_FAILURE;
     760        PR_DELETE(process);
     761        return PR_FAILURE;
    754762    }
    755763    return PR_SUCCESS;
     764#endif
    756765}
    757766
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette