VirtualBox

Changeset 24821 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Nov 20, 2009 1:33:26 PM (15 years ago)
Author:
vboxsync
Message:

xpcom/server.cpp: Close all file handles when daemonzining VBoxSVC.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/xpcom/server.cpp

    r24820 r24821  
    5353
    5454#include <stdio.h>
    55 
    56 // for the signal handler
    57 #include <signal.h>
     55#include <signal.h>     // for the signal handler
    5856#include <stdlib.h>
    5957#include <unistd.h>
    6058#include <errno.h>
    6159#include <getopt.h>
    62 
     60#include <sys/fcntl.h>
    6361#ifndef RT_OS_OS2
    6462# include <sys/resource.h>
     
    748746    {
    749747        { "automate",       no_argument,        NULL, 'a' },
    750 #if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    751748        { "auto-shutdown",  no_argument,        NULL, 'A' },
    752 #endif
    753749        { "daemonize",      no_argument,        NULL, 'd' },
    754750        { "pidfile",        required_argument,  NULL, 'p' },
    755 #if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    756751        { "pipe",           required_argument,  NULL, 'P' },
    757 #endif
    758752        { NULL,             0,                  NULL,  0  }
    759753    };
    760     int c;
    761 
     754    int  c;
    762755    bool fDaemonize = false;
    763 #ifndef RT_OS_OS2
    764     static int daemon_pipe_fds[2] = {-1, -1};
    765 #endif
     756    int  daemon_pipe_wr = -1;
    766757
    767758    for (;;)
     
    782773            }
    783774
    784 # if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    785775            /* Used together with '-P', see below. Internal use only. */
    786776            case 'A':
     
    789779                break;
    790780            }
    791 #endif
    792781
    793782            case 'd':
     
    803792            }
    804793
    805 # if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    806794            /* we need to exec on darwin, this is just an internal
    807795             * hack for passing the pipe fd along to the final child. */
    808796            case 'P':
    809797            {
    810                 daemon_pipe_fds[1] = atoi(optarg);
     798                daemon_pipe_wr = atoi(optarg);
    811799                break;
    812800            }
    813 #endif
    814801
    815802            default:
     
    834821    {
    835822        /* create a pipe for communication between child and parent */
     823        int daemon_pipe_fds[2] = {-1, -1};
    836824        if (pipe(daemon_pipe_fds) < 0)
    837825        {
     
    839827            return 1;
    840828        }
     829        daemon_pipe_wr = daemon_pipe_fds[1];
     830        int daemon_pipe_rd = daemon_pipe_fds[0];
    841831
    842832        pid_t childpid = fork();
     
    853843
    854844            /* close the writing end of the pipe */
    855             close(daemon_pipe_fds[1]);
     845            close(daemon_pipe_wr);
    856846
    857847            /* try to read a message from the pipe */
    858             char msg[10] = {0}; /* initialize so it's NULL terminated */
    859             if (read(daemon_pipe_fds[0], msg, sizeof(msg)) > 0)
     848            char msg[10 + 1];
     849            RT_ZERO(msg); /* initialize so it's NULL terminated */
     850            if (read(daemon_pipe_rd, msg, sizeof(msg) - 1) > 0)
    860851            {
    861852                if (strcmp(msg, "READY") == 0)
    862853                    fSuccess = true;
    863854                else
    864                     printf ("ERROR: Unknown message from child "
    865                             "process (%s)\n", msg);
     855                    printf ("ERROR: Unknown message from child process (%s)\n", msg);
    866856            }
    867857            else
     
    869859
    870860            /* close the reading end of the pipe as well and exit */
    871             close(daemon_pipe_fds[0]);
     861            close(daemon_pipe_rd);
    872862            return fSuccess ? 0 : 1;
    873863        }
     
    898888        }
    899889
    900         /* Redirect standard i/o streams to /dev/null */
    901         if (daemon_pipe_fds[0] > 2)
    902         {
    903             freopen ("/dev/null", "r", stdin);
    904             freopen ("/dev/null", "w", stdout);
    905             freopen ("/dev/null", "w", stderr);
    906         }
    907 
    908         /* close the reading end of the pipe */
    909         close(daemon_pipe_fds[0]);
    910 
    911 # if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
     890        /* Close all file handles except for the write end of the pipe. */
     891        int fdMax;
     892        struct rlimit lim;
     893        if (getrlimit(RLIMIT_NOFILE, &lim) == 0)
     894            fdMax = (int)RT_MIN(lim.rlim_cur, 65535); /* paranoia */
     895        else
     896            fdMax = 1024;
     897        for (int fd = 0; fd < fdMax; fd++)
     898            if (fd != daemon_pipe_wr)
     899                close(fd);
     900
     901        /* Make sure the pipe isn't any of the standard handles. */
     902        if (daemon_pipe_wr <= 2)
     903        {
     904            if (dup2(daemon_pipe_wr, 3) == 3)
     905            {
     906                close(daemon_pipe_wr);
     907                daemon_pipe_wr = 3;
     908            }
     909        }
     910
     911        /* Redirect the standard handles to NULL by opening /dev/null three times. */
     912        open("/dev/null", O_RDWR, 0);
     913        open("/dev/null", O_RDWR, 0);
     914        open("/dev/null", O_RDWR, 0);
     915
    912916        /*
    913917         * On leopard we're no longer allowed to use some of the core API's
     
    921925         * a frontend (debugger and strace don't contain any useful info).
    922926         */
    923         const char *apszArgs[7];
     927        const char *apszArgs[7 + 2];
    924928        unsigned i = 0;
    925929        apszArgs[i++] = argv[0];
    926930        apszArgs[i++] = "--pipe";
    927931        char szPipeArg[32];
    928         RTStrPrintf (szPipeArg, sizeof (szPipeArg), "%d", daemon_pipe_fds[1]);
     932        RTStrPrintf (szPipeArg, sizeof (szPipeArg), "%d", daemon_pipe_wr);
    929933        apszArgs[i++] = szPipeArg;
    930934        if (pszPidFile)
     
    938942        execv (apszArgs[0], (char * const *)apszArgs);
    939943        exit (126);
    940 # endif
    941944    }
    942945
     
    10461049        }
    10471050
    1048 #ifndef RT_OS_OS2
    1049         if (daemon_pipe_fds[1] >= 0)
     1051        if (daemon_pipe_wr >= 0)
    10501052        {
    10511053            printf ("\nStarting event loop....\n[send TERM signal to quit]\n");
    10521054            /* now we're ready, signal the parent process */
    1053             write(daemon_pipe_fds[1], "READY", strlen("READY"));
     1055            write(daemon_pipe_wr, "READY", strlen("READY"));
    10541056        }
    10551057        else
    1056 #endif
    10571058        {
    10581059            printf ("\nStarting event loop....\n[press Ctrl-C to quit]\n");
     
    11331134    }
    11341135
    1135 #ifndef RT_OS_OS2
    1136     if (daemon_pipe_fds[1] >= 0)
     1136    if (daemon_pipe_wr >= 0)
    11371137    {
    11381138        /* close writing end of the pipe as well */
    1139         close(daemon_pipe_fds[1]);
    1140     }
    1141 #endif
     1139        close(daemon_pipe_wr);
     1140    }
    11421141
    11431142    return 0;
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