VirtualBox

Ignore:
Timestamp:
Oct 11, 2010 4:30:54 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
66568
Message:

iprt/process: eliminate RTPROC_FLAGS_DAEMONIZE_DEPRECATED, rework starting a detached process on posix platforms and eliminate one useless fork(), avoid running

atexit functions in the temporary process

XPCOM: more detached process rework, block anything not going through IPRT, clos
e a few file descriptor inheritance leaks, and clean up the file descriptor pass
ing to VBoxXPCOMIPCD

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/posix/process-posix.cpp

    r33009 r33044  
    266266    AssertPtrReturn(pszExec, VERR_INVALID_POINTER);
    267267    AssertReturn(*pszExec, VERR_INVALID_PARAMETER);
    268     AssertReturn(!(fFlags & ~(RTPROC_FLAGS_DAEMONIZE_DEPRECATED | RTPROC_FLAGS_DETACHED | RTPROC_FLAGS_SERVICE)), VERR_INVALID_PARAMETER);
     268    AssertReturn(!(fFlags & ~(RTPROC_FLAGS_DETACHED | RTPROC_FLAGS_SERVICE)), VERR_INVALID_PARAMETER);
    269269    AssertReturn(!(fFlags & RTPROC_FLAGS_DETACHED) || !phProcess, VERR_INVALID_PARAMETER);
    270270    AssertReturn(hEnv != NIL_RTENV, VERR_INVALID_PARAMETER);
     
    346346    }
    347347
    348     /*
    349      * Spawn the child.
     348    pid_t pid = -1;
     349
     350    /*
     351     * Take care of detaching the process.
    350352     *
    351353     * HACK ALERT! Put the process into a new process group with pgid = pid
    352354     * to make sure it differs from that of the parent process to ensure that
    353      * the IPRT waipit call doesn't race anyone (read XPCOM) doing group wide
    354      * waits.
    355      */
    356     pid_t pid = -1;
     355     * the IPRT waitpid call doesn't race anyone (read XPCOM) doing group wide
     356     * waits. setsid() includes the setpgid() functionality.
     357     * 2010-10-11 XPCOM no longer waits for anything, but it cannot hurt.
     358     */
     359#ifndef RT_OS_OS2
     360    if (fFlags & RTPROC_FLAGS_DETACHED)
     361    {
     362# ifdef RT_OS_SOLARIS
     363        int templateFd = rtSolarisContractPreFork();
     364        if (templateFd == -1)
     365            return VERR_OPEN_FAILED;
     366# endif /* RT_OS_SOLARIS */
     367        pid = fork();
     368        if (!pid)
     369        {
     370# ifdef RT_OS_SOLARIS
     371            rtSolarisContractPostForkChild(templateFd);
     372# endif /* RT_OS_SOLARIS */
     373            setsid(); /* see comment above */
     374
     375            pid = -1;
     376            /* Child falls through to the actual spawn code below. */
     377        }
     378        else
     379        {
     380#ifdef RT_OS_SOLARIS
     381            rtSolarisContractPostForkParent(templateFd, pid);
     382#endif /* RT_OS_SOLARIS */
     383            if (pid > 0)
     384            {
     385                /* Must wait for the temporary process to avoid a zombie. */
     386                int status;
     387                waitpid(pid, &status, 0);
     388                /* Assume that something wasn't found. No detailed info. */
     389                if (status)
     390                    return VERR_PROCESS_NOT_FOUND;
     391                if (phProcess)
     392                    *phProcess = 0;
     393                return VINF_SUCCESS;
     394            }
     395            return RTErrConvertFromErrno(errno);
     396        }
     397    }
     398#endif
     399
     400    /*
     401     * Spawn the child.
     402     *
     403     * Any spawn code MUST not execute any atexit functions if it is for a
     404     * detached process. It would lead to running the atexit functions which
     405     * make only sense for the parent. libORBit e.g. gets confused by multiple
     406     * execution. Remember, there was only a fork() so far, and until exec()
     407     * is successfully run there is nothing which would prevent doing anything
     408     * silly with the (duplicated) file descriptors.
     409     */
    357410#ifdef HAVE_POSIX_SPAWN
    358411    /** @todo OS/2: implement DETACHED (BACKGROUND stuff), see VbglR3Daemonize.  */
    359     /** @todo Try do the detach thing with posix spawn.  */
    360     if (   !(fFlags & (RTPROC_FLAGS_DAEMONIZE_DEPRECATED | RTPROC_FLAGS_DETACHED))
    361         && uid == ~(uid_t)0
    362         && gid == ~(gid_t)0
    363         )
     412    if (   uid == ~(uid_t)0
     413        && gid == ~(gid_t)0)
    364414    {
    365415        /* Spawn attributes. */
     
    428478            if (!rc)
    429479            {
     480                /* For a detached process this happens in the temp process, so
     481                 * it's not worth doing anything as this process must exit. */
     482                if (fFlags & RTPROC_FLAGS_DETACHED)
     483                _Exit(0);
    430484                if (phProcess)
    431485                    *phProcess = pid;
     
    433487            }
    434488        }
     489        /* For a detached process this happens in the temp process, so
     490         * it's not worth doing anything as this process must exit. */
     491        if (fFlags & RTPROC_FLAGS_DETACHED)
     492            _Exit(124);
    435493    }
    436494    else
     
    448506            rtSolarisContractPostForkChild(templateFd);
    449507#endif /* RT_OS_SOLARIS */
    450             setpgid(0, 0); /* see comment above */
     508            if (!(fFlags & RTPROC_FLAGS_DETACHED))
     509                setpgid(0, 0); /* see comment above */
    451510
    452511            /*
     
    457516            {
    458517                if (setgid(gid))
    459                     exit(126);
     518                {
     519                    if (fFlags & RTPROC_FLAGS_DETACHED)
     520                        _Exit(126);
     521                    else
     522                        exit(126);
     523                }
    460524            }
    461525
     
    463527            {
    464528                if (setuid(uid))
    465                     exit(126);
     529                {
     530                    if (fFlags & RTPROC_FLAGS_DETACHED)
     531                        _Exit(126);
     532                    else
     533                        exit(126);
     534                }
    466535            }
    467536#endif
     
    479548                    int rc2 = dup2(fd, i);
    480549                    if (rc2 != i)
    481                         exit(125);
     550                    {
     551                        if (fFlags & RTPROC_FLAGS_DETACHED)
     552                            _Exit(125);
     553                        else
     554                            exit(125);
     555                    }
    482556                    for (int j = i + 1; j < 3; j++)
    483557                        if (aStdFds[j] == fd)
     
    492566
    493567            /*
    494              * Daemonize the process if requested.
    495              */
    496             if (fFlags & (RTPROC_FLAGS_DAEMONIZE_DEPRECATED | RTPROC_FLAGS_DETACHED))
    497             {
    498                 rc = RTProcDaemonizeUsingFork(true /*fNoChDir*/,
    499                                               !(fFlags & RTPROC_FLAGS_DAEMONIZE_DEPRECATED) /*fNoClose*/,
    500                                               NULL /* pszPidFile */);
    501                 if (RT_FAILURE(rc))
    502                 {
    503                     /* parent */
    504                     AssertReleaseMsgFailed(("RTProcDaemonize returns %Rrc errno=%d\n", rc, errno));
    505                     exit(127);
    506                 }
    507                 /* daemonized child */
    508             }
    509 
    510             /*
    511568             * Finally, execute the requested program.
    512569             */
     
    520577                RTAssertMsg2Weak("execve returns %d errno=%d\n", rc, errno);
    521578            RTAssertReleasePanic();
    522             exit(127);
     579            if (fFlags & RTPROC_FLAGS_DETACHED)
     580                _Exit(127);
     581            else
     582                exit(127);
    523583        }
    524584#ifdef RT_OS_SOLARIS
     
    527587        if (pid > 0)
    528588        {
     589            /* For a detached process this happens in the temp process, so
     590             * it's not worth doing anything as this process must exit. */
     591            if (fFlags & RTPROC_FLAGS_DETACHED)
     592                _Exit(0);
    529593            if (phProcess)
    530594                *phProcess = pid;
    531             else if (fFlags & (RTPROC_FLAGS_DAEMONIZE_DEPRECATED | RTPROC_FLAGS_DETACHED))
    532             {
    533                 /* If the process is detached straight away wait for the
    534                  * intermediate process to exit (it should do that quickly)
    535                  * if the caller didn't want to know the PID. If it wants the
    536                  * PID it's his job to wait for it or he gets a zombie. */
    537                 waitpid(pid, NULL, 0);
    538             }
    539595            return VINF_SUCCESS;
    540596        }
    541         rc = errno;
    542     }
    543 
     597        /* For a detached process this happens in the temp process, so
     598         * it's not worth doing anything as this process must exit. */
     599        if (fFlags & RTPROC_FLAGS_DETACHED)
     600            _Exit(124);
     601        return RTErrConvertFromErrno(errno);
     602    }
    544603
    545604    return VERR_NOT_IMPLEMENTED;
Note: See TracChangeset for help on using the changeset viewer.

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