VirtualBox

Ignore:
Timestamp:
Jan 22, 2008 2:19:50 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
27420
Message:

Put VbglR3Daemonize into a separate file and merged the solaris and linux code. (untested)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp

    r6434 r6445  
    2424# define INCL_ERRORS
    2525# include <os2.h>
    26 
    27 # include <iprt/alloca.h>
    28 # include <iprt/string.h>
    29 #elif defined(RT_OS_LINUX)
    30 # include <sys/stat.h>
    31 # include <fcntl.h>
    32 # include <stdlib.h>
    33 # include <unistd.h>
    34 # include <sys/time.h>
    35 # include <sys/resource.h>
    3626#elif defined(RT_OS_SOLARIS)
    3727# include <sys/types.h>
    3828# include <sys/stat.h>
    3929# include <errno.h>
    40 # include <stdio.h>
    41 # include <stdlib.h>
    4230# include <unistd.h>
    43 # include <signal.h>
    44 # include <fcntl.h>
    4531#endif
    4632
     
    5137#include <iprt/assert.h>
    5238#include <iprt/mem.h>
     39#include <iprt/alloca.h>
    5340#include <VBox/VBoxGuest.h>
    5441
     
    187174
    188175#else
    189     /* Default implementation (linux, solaris). */
     176    /* Default implementation - PORTME: Do not use this without testings that error passing works! */
    190177    int rc2 = VERR_INTERNAL_ERROR;
    191178    int rc = RTFileIoCtl(g_File, (int)iFunction, pvData, cbData, &rc2);
     
    335322}
    336323
    337 
    338 /**
    339  * Daemonize the process for running in the background.
    340  *
    341  * @returns 0 on success
    342  *
    343  * @param   nochdir     Pass 0 to change working directory to root.
    344  * @param   noclose     Pass 0 to redirect standard file streams to /dev/null.
    345  */
    346 VBGLR3DECL(int) VbglR3Daemonize(int nochdir, int noclose)
    347 {
    348 #if defined(RT_OS_LINUX)
    349     /** rlimit structure for finding out how many open files we may have. */
    350     struct rlimit rlim;
    351 
    352     /* To make sure that we are not currently a session leader, we must first fork and let
    353        the parent process exit, as a newly created child is never session leader.  This will
    354        allow us to call setsid() later. */
    355     if (fork() != 0)
    356     {
    357         exit(0);
    358     }
    359     /* Find the maximum number of files we can have open and close them all. */
    360     if (0 != getrlimit(RLIMIT_NOFILE, &rlim))
    361     {
    362         /* For some reason the call failed.  In that case we will just close the three
    363            standard files and hope. */
    364         rlim.rlim_cur = 3;
    365     }
    366     for (unsigned int i = 0; i < rlim.rlim_cur; ++i)
    367     {
    368         close(i);
    369     }
    370     /* Change to the root directory to avoid keeping the one we were started in open. */
    371     chdir("/");
    372     /* Set our umask to zero. */
    373     umask(0);
    374     /* And open /dev/null on stdin/out/err. */
    375     open("/dev/null", O_RDONLY);
    376     open("/dev/null", O_WRONLY);
    377     dup(1);
    378     /* Detach from the controlling terminal by creating our own session, to avoid receiving
    379        signals from the old session. */
    380     setsid();
    381     /* And fork again, letting the parent exit, to make us a child of init and avoid zombies. */
    382     if (fork() != 0)
    383     {
    384         exit(0);
    385     }
    386     NOREF(nochdir);
    387     NOREF(noclose);
    388 
    389     return 0;
    390 
    391 #elif defined(RT_OS_OS2)
    392     PPIB pPib;
    393     PTIB pTib;
    394     DosGetInfoBlocks(&pTib, &pPib);
    395 
    396     /* Get the full path to the executable. */
    397     char szExe[CCHMAXPATH];
    398     APIRET rc = DosQueryModuleName(pPib->pib_hmte, sizeof(szExe), szExe);
    399     if (rc)
    400     {
    401         errno = EDOOFUS;
    402         return -1;
    403     }
    404 
    405     /* calc the length of the command line. */
    406     char *pch = pPib->pib_pchcmd;
    407     size_t cch0 = strlen(pch);
    408     pch += cch0 + 1;
    409     size_t cch1 = strlen(pch);
    410     pch += cch1 + 1;
    411     char *pchArgs;
    412     if (cch1 && *pch)
    413     {
    414         do  pch = strchr(pch, '\0') + 1;
    415         while (*pch);
    416 
    417         size_t cchTotal = pch - pPib->pib_pchcmd;
    418         pchArgs = (char *)alloca(cchTotal + sizeof("--daemonized\0\0"));
    419         memcpy(pchArgs, pPib->pib_pchcmd, cchTotal - 1);
    420         memcpy(pchArgs + cchTotal - 1, "--daemonized\0\0", sizeof("--daemonized\0\0"));
    421     }
    422     else
    423     {
    424         size_t cchTotal = pch - pPib->pib_pchcmd + 1;
    425         pchArgs = (char *)alloca(cchTotal + sizeof(" --daemonized "));
    426         memcpy(pchArgs, pPib->pib_pchcmd, cch0 + 1);
    427         pch = pchArgs + cch0 + 1;
    428         memcpy(pch, " --daemonized ", sizeof(" --daemonized ") - 1);
    429         pch += sizeof(" --daemonized ") - 1;
    430         if (cch1)
    431             memcpy(pch, pPib->pib_pchcmd + cch0 + 1, cch1 + 2);
    432         else
    433             pch[0] = pch[1] = '\0';
    434     }
    435 
    436     /* spawn a detach process  */
    437     char szObj[128];
    438     RESULTCODES ResCodes = { 0, 0 };
    439     szObj[0] = '\0';
    440     rc = DosExecPgm(szObj, sizeof(szObj), EXEC_BACKGROUND, (PCSZ)pchArgs, NULL, &ResCodes, (PCSZ)szExe);
    441     if (rc)
    442     {
    443         /** @todo Change this to some standard log/print error?? */
    444         /* VBoxServiceError("DosExecPgm failed with rc=%d and szObj='%s'\n", rc, szObj); */
    445         errno = EDOOFUS;
    446         return -1;
    447     }
    448     DosExit(EXIT_PROCESS, 0);
    449     return -1;
    450 
    451 #elif defined(RT_OS_SOLARIS)
    452     if (getppid() == 1) /* We already belong to init process */
    453         return -1;
    454 
    455     pid_t pid = fork();
    456     if (pid < 0)         /* The fork() failed. Bad. */
    457         return -1;
    458 
    459     if (pid > 0)         /* Quit parent process */
    460         exit(0);
    461 
    462     /*
    463      * The orphaned child becomes a daemon after attaching to init. We need to get
    464      * rid of signals, file descriptors & other stuff we inherited from the parent.
    465      */
    466     pid_t newpgid = setsid();
    467     if (newpgid < 0)     /* Failed to create new sesion */
    468         return -1;
    469 
    470     /* BSD daemon style. */
    471     if (!noclose)
    472     {
    473         /* Open stdin(0), stdout(1) and stderr(2) to /dev/null */
    474         int fd = open("/dev/null", O_RDWR);
    475         dup2(fd, STDIN_FILENO);
    476         dup2(fd, STDOUT_FILENO);
    477         dup2(fd, STDERR_FILENO);
    478         if (fd > 2)
    479             close(fd);
    480     }
    481 
    482     /* Switch our current directory to root */
    483     if (!nochdir)
    484         chdir("/");     /* @todo Check if switching to '/' is the convention for Solaris daemons. */
    485 
    486     /* Set file permission to something secure, as we need to run as root on Solaris */
    487     umask(027);
    488     return 0;
    489 #endif
    490 }
    491 
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