Changeset 6445 in vbox for trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp
- Timestamp:
- Jan 22, 2008 2:19:50 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 27420
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp
r6434 r6445 24 24 # define INCL_ERRORS 25 25 # 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>36 26 #elif defined(RT_OS_SOLARIS) 37 27 # include <sys/types.h> 38 28 # include <sys/stat.h> 39 29 # include <errno.h> 40 # include <stdio.h>41 # include <stdlib.h>42 30 # include <unistd.h> 43 # include <signal.h>44 # include <fcntl.h>45 31 #endif 46 32 … … 51 37 #include <iprt/assert.h> 52 38 #include <iprt/mem.h> 39 #include <iprt/alloca.h> 53 40 #include <VBox/VBoxGuest.h> 54 41 … … 187 174 188 175 #else 189 /* Default implementation (linux, solaris).*/176 /* Default implementation - PORTME: Do not use this without testings that error passing works! */ 190 177 int rc2 = VERR_INTERNAL_ERROR; 191 178 int rc = RTFileIoCtl(g_File, (int)iFunction, pvData, cbData, &rc2); … … 335 322 } 336 323 337 338 /**339 * Daemonize the process for running in the background.340 *341 * @returns 0 on success342 *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 let353 the parent process exit, as a newly created child is never session leader. This will354 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 three363 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 receiving379 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 else423 {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 else433 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 get464 * 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 #endif490 }491
Note:
See TracChangeset
for help on using the changeset viewer.