Changeset 6356 in vbox for trunk/src/VBox/Additions/common/VBoxGuestLib
- Timestamp:
- Jan 15, 2008 1:27:51 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 27270
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp
r6280 r6356 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 #elif defined(RT_OS_SOLARIS) 37 # include <sys/types.h> 38 # include <sys/stat.h> 39 # include <stdio.h> 40 # include <stdlib.h> 41 # include <unistd.h> 42 # include <signal.h> 43 # include <fcntl.h> 26 44 #endif 27 45 … … 290 308 } 291 309 310 292 311 /** 293 312 * Change the IRQ filter mask. … … 304 323 } 305 324 325 326 /** 327 * Daemonize the process for running in the background. 328 * 329 * @returns 0 on success 330 * 331 * @param nochdir Pass 0 to change working directory to root. 332 * @param noclose Pass 0 to redirect standard file streams to /dev/null. 333 */ 334 VBGLR3DECL(int) VbglR3Daemonize(int nochdir, int noclose) 335 { 336 #if defined(RT_OS_LINUX) 337 /** rlimit structure for finding out how many open files we may have. */ 338 struct rlimit rlim; 339 340 /* To make sure that we are not currently a session leader, we must first fork and let 341 the parent process exit, as a newly created child is never session leader. This will 342 allow us to call setsid() later. */ 343 if (fork() != 0) 344 { 345 exit(0); 346 } 347 /* Find the maximum number of files we can have open and close them all. */ 348 if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) 349 { 350 /* For some reason the call failed. In that case we will just close the three 351 standard files and hope. */ 352 rlim.rlim_cur = 3; 353 } 354 for (unsigned int i = 0; i < rlim.rlim_cur; ++i) 355 { 356 close(i); 357 } 358 /* Change to the root directory to avoid keeping the one we were started in open. */ 359 chdir("/"); 360 /* Set our umask to zero. */ 361 umask(0); 362 /* And open /dev/null on stdin/out/err. */ 363 open("/dev/null", O_RDONLY); 364 open("/dev/null", O_WRONLY); 365 dup(1); 366 /* Detach from the controlling terminal by creating our own session, to avoid receiving 367 signals from the old session. */ 368 setsid(); 369 /* And fork again, letting the parent exit, to make us a child of init and avoid zombies. */ 370 if (fork() != 0) 371 { 372 exit(0); 373 } 374 NOREF(nochdir); 375 NOREF(noclose); 376 377 return 0; 378 379 #elif defined(RT_OS_OS2) 380 PPIB pPib; 381 PTIB pTib; 382 DosGetInfoBlocks(&pTib, &pPib); 383 384 /* Get the full path to the executable. */ 385 char szExe[CCHMAXPATH]; 386 APIRET rc = DosQueryModuleName(pPib->pib_hmte, sizeof(szExe), szExe); 387 if (rc) 388 { 389 errno = EDOOFUS; 390 return -1; 391 } 392 393 /* calc the length of the command line. */ 394 char *pch = pPib->pib_pchcmd; 395 size_t cch0 = strlen(pch); 396 pch += cch0 + 1; 397 size_t cch1 = strlen(pch); 398 pch += cch1 + 1; 399 char *pchArgs; 400 if (cch1 && *pch) 401 { 402 do pch = strchr(pch, '\0') + 1; 403 while (*pch); 404 405 size_t cchTotal = pch - pPib->pib_pchcmd; 406 pchArgs = (char *)alloca(cchTotal + sizeof("--daemonized\0\0")); 407 memcpy(pchArgs, pPib->pib_pchcmd, cchTotal - 1); 408 memcpy(pchArgs + cchTotal - 1, "--daemonized\0\0", sizeof("--daemonized\0\0")); 409 } 410 else 411 { 412 size_t cchTotal = pch - pPib->pib_pchcmd + 1; 413 pchArgs = (char *)alloca(cchTotal + sizeof(" --daemonized ")); 414 memcpy(pchArgs, pPib->pib_pchcmd, cch0 + 1); 415 pch = pchArgs + cch0 + 1; 416 memcpy(pch, " --daemonized ", sizeof(" --daemonized ") - 1); 417 pch += sizeof(" --daemonized ") - 1; 418 if (cch1) 419 memcpy(pch, pPib->pib_pchcmd + cch0 + 1, cch1 + 2); 420 else 421 pch[0] = pch[1] = '\0'; 422 } 423 424 /* spawn a detach process */ 425 char szObj[128]; 426 RESULTCODES ResCodes = { 0, 0 }; 427 szObj[0] = '\0'; 428 rc = DosExecPgm(szObj, sizeof(szObj), EXEC_BACKGROUND, (PCSZ)pchArgs, NULL, &ResCodes, (PCSZ)szExe); 429 if (rc) 430 { 431 /** @todo Change this to some standard log/print error?? */ 432 /* VBoxServiceError("DosExecPgm failed with rc=%d and szObj='%s'\n", rc, szObj); */ 433 errno = EDOOFUS; 434 return -1; 435 } 436 DosExit(EXIT_PROCESS, 0); 437 return -1; 438 439 #elif defined(RT_OS_SOLARIS) 440 if (getppid() == 1) /* We already belong to init process */ 441 return -1; 442 443 pid_t pid = fork(); 444 if (pid < 0) /* The fork() failed. Bad. */ 445 return -1; 446 447 if (pid > 0) /* Quit parent process */ 448 exit(0); 449 450 /* 451 * The orphaned child becomes a daemon after attaching to init. We need to get 452 * rid of signals, file descriptors & other stuff we inherited from the parent. 453 */ 454 pid_t newpgid = setsid(); 455 if (newpgid < 0) /* Failed to create new sesion */ 456 return -1; 457 458 /* BSD daemon style. */ 459 if (!noclose) 460 { 461 /* Open stdin(0), stdout(1) and stderr(2) to /dev/null */ 462 int fd = open("/dev/null", O_RDWR); 463 dup2(fd, STDIN_FILENO); 464 dup2(fd, STDOUT_FILENO); 465 dup2(fd, STDERR_FILENO); 466 if (fd > 2) 467 close(fd); 468 } 469 470 /* Switch our current directory to root */ 471 if (!nochdir) 472 chdir("/"); /* @todo Check if switching to '/' is the convention for Solaris daemons. */ 473 474 /* Set file permission to something secure, as we need to run as root on Solaris */ 475 umask(027); 476 return 0; 477 #endif 478 } 479
Note:
See TracChangeset
for help on using the changeset viewer.