VirtualBox

Changeset 57730 in vbox for trunk


Ignore:
Timestamp:
Sep 14, 2015 8:27:42 AM (9 years ago)
Author:
vboxsync
Message:

Windows build fix

Location:
trunk/src/VBox/Additions/common/VBoxGuestLib
Files:
2 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk

    r56294 r57730  
    117117        VBoxGuestR3LibStat.cpp \
    118118        VBoxGuestR3LibTime.cpp \
    119         VBoxGuestR3LibModule.cpp
     119        VBoxGuestR3LibModule.cpp \
     120        VBoxGuestR3LibPidFile.cpp
    120121ifneq ($(KBUILD_TARGET),win) ## @todo get rid of this hack (as soon as it's all implemented / #defined).
    121122 VBoxGuestR3Lib_SOURCES   += \
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDaemonize.cpp

    r57358 r57730  
    5252#endif
    5353
    54 #include <iprt/file.h>
    5554#include <iprt/process.h>
    5655#include <iprt/string.h>
     
    251250#endif
    252251}
    253 
    254 
    255 /**
    256  * Creates a PID File and returns the open file descriptor.
    257  *
    258  * On DOS based system, file sharing (deny write) is used for locking the PID
    259  * file.
    260  *
    261  * On Unix-y systems, an exclusive advisory lock is used for locking the PID
    262  * file since the file sharing support is usually missing there.
    263  *
    264  * This API will overwrite any existing PID Files without a lock on them, on the
    265  * assumption that they are stale files which an old process did not properly
    266  * clean up.
    267  *
    268  * @returns IPRT status code.
    269  * @param   pszPath  The path and filename to create the PID File under
    270  * @param   phFile   Where to store the file descriptor of the open (and locked
    271  *                   on Unix-y systems) PID File. On failure, or if another
    272  *                   process owns the PID File, this will be set to NIL_RTFILE.
    273  */
    274 VBGLR3DECL(int) VbglR3PidFile(const char *pszPath, PRTFILE phFile)
    275 {
    276     AssertPtrReturn(pszPath, VERR_INVALID_PARAMETER);
    277     AssertPtrReturn(phFile, VERR_INVALID_PARAMETER);
    278     *phFile = NIL_RTFILE;
    279 
    280     RTFILE hPidFile;
    281     int rc = RTFileOpen(&hPidFile, pszPath,
    282                         RTFILE_O_READWRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE
    283                         | (0644 << RTFILE_O_CREATE_MODE_SHIFT));
    284     if (RT_SUCCESS(rc))
    285     {
    286 #if !defined(RT_OS_WINDOWS) && !defined(RT_OS_OS2)
    287         /** @todo using size 0 for locking means lock all on Posix.
    288          * We should adopt this as our convention too, or something
    289          * similar. */
    290         rc = RTFileLock(hPidFile, RTFILE_LOCK_WRITE, 0, 0);
    291         if (RT_FAILURE(rc))
    292             RTFileClose(hPidFile);
    293         else
    294 #endif
    295         {
    296             char szBuf[256];
    297             size_t cbPid = RTStrPrintf(szBuf, sizeof(szBuf), "%d\n",
    298                                        RTProcSelf());
    299             RTFileWrite(hPidFile, szBuf, cbPid, NULL);
    300             *phFile = hPidFile;
    301         }
    302     }
    303     return rc;
    304 }
    305 
    306 
    307 /**
    308  * Close and remove an open PID File.
    309  *
    310  * @param  pszPath  The path to the PID File,
    311  * @param  hFile    The handle for the file. NIL_RTFILE is ignored as usual.
    312  */
    313 VBGLR3DECL(void) VbglR3ClosePidFile(const char *pszPath, RTFILE hFile)
    314 {
    315     AssertPtrReturnVoid(pszPath);
    316     if (hFile != NIL_RTFILE)
    317     {
    318 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    319         RTFileWriteAt(hFile, 0, "-1", 2, NULL);
    320 #else
    321         RTFileDelete(pszPath);
    322 #endif
    323         RTFileClose(hFile);
    324     }
    325 }
    326 
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibPidFile.cpp

    r57729 r57730  
    11/** $Id$ */
    22/** @file
    3  * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, daemonize a process.
     3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions,
     4 * Create a PID file.
    45 */
    56
    67/*
    7  * Copyright (C) 2007-2015 Oracle Corporation
     8 * Copyright (C) 2015 Oracle Corporation
    89 *
    910 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2930*   Header Files                                                                                                                 *
    3031*********************************************************************************************************************************/
    31 #if defined(RT_OS_OS2)
    32 # define INCL_BASE
    33 # define INCL_ERRORS
    34 # include <os2.h>
    35 
    36 # include <iprt/alloca.h>
    37 # include <iprt/string.h>
    38 
    39 #elif defined(RT_OS_WINDOWS)
    40 # error "PORTME"
    41 
    42 #else /* the unices */
    43 # include <sys/types.h>
    44 # include <sys/stat.h>
    45 # include <sys/wait.h>
    46 # include <stdio.h>
    47 # include <fcntl.h>
    48 # include <stdlib.h>
    49 # include <unistd.h>
    50 # include <signal.h>
    51 # include <errno.h>
    52 #endif
    53 
    5432#include <iprt/file.h>
     33#include <iprt/string.h>
    5534#include <iprt/process.h>
    56 #include <iprt/string.h>
    5735#include "VBGLR3Internal.h"
    58 
    59 
    60 /**
    61  * Daemonize the process for running in the background.
    62  *
    63  * This is supposed to do the same job as the BSD daemon() call.
    64  *
    65  * @returns 0 on success
    66  *
    67  * @param   fNoChDir    Pass false to change working directory to root.
    68  * @param   fNoClose    Pass false to redirect standard file streams to /dev/null.
    69  * @param   fRespawn    Restart the daemonised process after five seconds if it
    70  *                      terminates abnormally.
    71  * @param   pcRespawn   Where to store a count of how often we have respawned,
    72  *                      intended for avoiding error spamming.  Optional.
    73  *
    74  * @todo    Use RTProcDaemonize instead of this.
    75  * @todo    Implement fRespawn on OS/2.
    76  * @todo    Make the respawn interval configurable.  But not until someone
    77  *          actually needs that.
    78  */
    79 VBGLR3DECL(int) VbglR3Daemonize(bool fNoChDir, bool fNoClose, bool fRespawn, unsigned *pcRespawn)
    80 {
    81 #if defined(RT_OS_OS2)
    82     PPIB pPib;
    83     PTIB pTib;
    84     DosGetInfoBlocks(&pTib, &pPib);
    85 
    86     AssertRelease(!fRespawn);
    87     /* Get the full path to the executable. */
    88     char szExe[CCHMAXPATH];
    89     APIRET rc = DosQueryModuleName(pPib->pib_hmte, sizeof(szExe), szExe);
    90     if (rc)
    91         return RTErrConvertFromOS2(rc);
    92 
    93     /* calc the length of the command line. */
    94     char *pch = pPib->pib_pchcmd;
    95     size_t cch0 = strlen(pch);
    96     pch += cch0 + 1;
    97     size_t cch1 = strlen(pch);
    98     pch += cch1 + 1;
    99     char *pchArgs;
    100     if (cch1 && *pch)
    101     {
    102         do  pch = strchr(pch, '\0') + 1;
    103         while (*pch);
    104 
    105         size_t cchTotal = pch - pPib->pib_pchcmd;
    106         pchArgs = (char *)alloca(cchTotal + sizeof("--daemonized\0\0"));
    107         memcpy(pchArgs, pPib->pib_pchcmd, cchTotal - 1);
    108         memcpy(pchArgs + cchTotal - 1, "--daemonized\0\0", sizeof("--daemonized\0\0"));
    109     }
    110     else
    111     {
    112         size_t cchTotal = pch - pPib->pib_pchcmd + 1;
    113         pchArgs = (char *)alloca(cchTotal + sizeof(" --daemonized "));
    114         memcpy(pchArgs, pPib->pib_pchcmd, cch0 + 1);
    115         pch = pchArgs + cch0 + 1;
    116         memcpy(pch, " --daemonized ", sizeof(" --daemonized ") - 1);
    117         pch += sizeof(" --daemonized ") - 1;
    118         if (cch1)
    119             memcpy(pch, pPib->pib_pchcmd + cch0 + 1, cch1 + 2);
    120         else
    121             pch[0] = pch[1] = '\0';
    122     }
    123 
    124     /* spawn a detach process  */
    125     char szObj[128];
    126     RESULTCODES ResCodes = { 0, 0 };
    127     szObj[0] = '\0';
    128     rc = DosExecPgm(szObj, sizeof(szObj), EXEC_BACKGROUND, (PCSZ)pchArgs, NULL, &ResCodes, (PCSZ)szExe);
    129     if (rc)
    130     {
    131         /** @todo Change this to some standard log/print error?? */
    132         /* VBoxServiceError("DosExecPgm failed with rc=%d and szObj='%s'\n", rc, szObj); */
    133         return RTErrConvertFromOS2(rc);
    134     }
    135     DosExit(EXIT_PROCESS, 0);
    136     return VERR_GENERAL_FAILURE;
    137 
    138 #elif defined(RT_OS_WINDOWS)
    139 # error "PORTME"
    140 
    141 #else /* the unices */
    142     /*
    143      * Fork the child process in a new session and quit the parent.
    144      *
    145      * - fork once and create a new session (setsid). This will detach us
    146      *   from the controlling tty meaning that we won't receive the SIGHUP
    147      *   (or any other signal) sent to that session.
    148      * - The SIGHUP signal is ignored because the session/parent may throw
    149      *   us one before we get to the setsid.
    150      * - When the parent exit(0) we will become an orphan and re-parented to
    151      *   the init process.
    152      * - Because of the Linux / System V semantics of assigning the controlling
    153      *   tty automagically when a session leader first opens a tty, we will
    154      *   fork() once more on Linux to get rid of the session leadership role.
    155      */
    156 
    157     struct sigaction OldSigAct;
    158     struct sigaction SigAct;
    159     RT_ZERO(SigAct);
    160     SigAct.sa_handler = SIG_IGN;
    161     int rcSigAct = sigaction(SIGHUP, &SigAct, &OldSigAct);
    162 
    163     pid_t pid = fork();
    164     if (pid == -1)
    165         return RTErrConvertFromErrno(errno);
    166     if (pid != 0)
    167         exit(0);
    168 
    169     /*
    170      * The orphaned child becomes is reparented to the init process.
    171      * We create a new session for it (setsid), point the standard
    172      * file descriptors to /dev/null, and change to the root directory.
    173      */
    174     pid_t newpgid = setsid();
    175     int SavedErrno = errno;
    176     if (rcSigAct != -1)
    177         sigaction(SIGHUP, &OldSigAct, NULL);
    178     if (newpgid == -1)
    179         return RTErrConvertFromErrno(SavedErrno);
    180 
    181     if (!fNoClose)
    182     {
    183         /* Open stdin(0), stdout(1) and stderr(2) as /dev/null. */
    184         int fd = open("/dev/null", O_RDWR);
    185         if (fd == -1) /* paranoia */
    186         {
    187             close(STDIN_FILENO);
    188             close(STDOUT_FILENO);
    189             close(STDERR_FILENO);
    190             fd = open("/dev/null", O_RDWR);
    191         }
    192         if (fd != -1)
    193         {
    194             dup2(fd, STDIN_FILENO);
    195             dup2(fd, STDOUT_FILENO);
    196             dup2(fd, STDERR_FILENO);
    197             if (fd > 2)
    198                 close(fd);
    199         }
    200     }
    201 
    202     if (!fNoChDir)
    203         chdir("/");
    204 
    205     /*
    206      * Change the umask - this is non-standard daemon() behavior.
    207      */
    208     umask(027);
    209 
    210 # ifdef RT_OS_LINUX
    211     /*
    212      * And fork again to lose session leader status (non-standard daemon()
    213      * behaviour).
    214      */
    215     pid = fork();
    216     if (pid == -1)
    217         return RTErrConvertFromErrno(errno);
    218     if (pid != 0)
    219         exit(0);
    220 # endif /* RT_OS_LINUX */
    221 
    222     if (fRespawn)
    223     {
    224         /* We implement re-spawning as a third fork(), with the parent process
    225          * monitoring the child and re-starting it after a delay if it exits
    226          * abnormally. */
    227         unsigned cRespawn = 0;
    228         for (;;)
    229         {
    230             int iStatus, rcWait;
    231 
    232             if (pcRespawn != NULL)
    233                 *pcRespawn = cRespawn;
    234             pid = fork();
    235             if (pid == -1)
    236                 return RTErrConvertFromErrno(errno);
    237             if (pid == 0)
    238                 return VINF_SUCCESS;
    239             do
    240                 rcWait = waitpid(pid, &iStatus, 0);
    241             while (rcWait == -1 && errno == EINTR);
    242             if (rcWait == -1)
    243                 exit(1);
    244             if (WIFEXITED(iStatus) && WEXITSTATUS(iStatus) == 0)
    245                 exit(0);
    246             sleep(5);
    247             ++cRespawn;
    248         }
    249     }
    250     return VINF_SUCCESS;
    251 #endif
    252 }
    253 
    25436
    25537/**
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