Changeset 11337 in vbox for trunk/src/VBox/Runtime/r3/posix
- Timestamp:
- Aug 11, 2008 3:15:13 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/process-posix.cpp
r8245 r11337 38 38 #include <stdlib.h> 39 39 #include <errno.h> 40 #include <sys/types.h> 40 41 #include <sys/stat.h> 41 42 #include <sys/wait.h> 43 #include <fcntl.h> 42 44 #include <signal.h> 43 45 #if defined(RT_OS_LINUX) || defined(RT_OS_OS2) … … 275 277 } 276 278 279 /** 280 * Daemonize the current process, making it a background process. The current 281 * process will exit if daemonizing is successful. 282 * 283 * @returns iprt status code. 284 * @param fNoChDir Pass false to change working directory to "/". 285 * @param fNoClose Pass false to redirect standard file streams to the null device. 286 * @param pszPidfile Path to a file to write the process id of the daemon 287 * process to. Daemonizing will fail if this file already 288 * exists or cannot be written. May be NULL. 289 */ 290 RTR3DECL(int) RTProcDaemonize(bool fNoChDir, bool fNoClose, const char *pszPidfile) 291 { 292 /* 293 * Fork the child process in a new session and quit the parent. 294 * 295 * - fork once and create a new session (setsid). This will detach us 296 * from the controlling tty meaning that we won't receive the SIGHUP 297 * (or any other signal) sent to that session. 298 * - The SIGHUP signal is ignored because the session/parent may throw 299 * us one before we get to the setsid. 300 * - When the parent exit(0) we will become an orphan and re-parented to 301 * the init process. 302 * - Because of the sometimes unexpected semantics of assigning the 303 * controlling tty automagically when a session leader first opens a tty, 304 * we will fork() once more to get rid of the session leadership role. 305 */ 306 307 /* We start off by opening the pidfile, so that we can fail straight away 308 * if it already exists. */ 309 int fdPidfile = -1; 310 if (pszPidfile != NULL) 311 { 312 /* @note the exclusive create is not guaranteed on all file 313 * systems (e.g. NFSv2) */ 314 if ((fdPidfile = open(pszPidfile, O_RDWR | O_CREAT | O_EXCL, 0644)) == -1) 315 return RTErrConvertFromErrno(errno); 316 } 317 318 /* Ignore SIGHUP straight away. */ 319 struct sigaction OldSigAct; 320 struct sigaction SigAct; 321 memset(&SigAct, 0, sizeof(SigAct)); 322 SigAct.sa_handler = SIG_IGN; 323 int rcSigAct = sigaction(SIGHUP, &SigAct, &OldSigAct); 324 325 /* First fork, to become independent process. */ 326 pid_t pid = fork(); 327 if (pid == -1) 328 return RTErrConvertFromErrno(errno); 329 if (pid != 0) 330 { 331 /* Parent exits, no longer necessary. Child creates gets reparented 332 * to the init process. */ 333 exit(0); 334 } 335 336 /* Create new session, fix up the standard file descriptors and the 337 * current working directory. */ 338 pid_t newpgid = setsid(); 339 int SavedErrno = errno; 340 if (rcSigAct != -1) 341 sigaction(SIGHUP, &OldSigAct, NULL); 342 if (newpgid == -1) 343 return RTErrConvertFromErrno(SavedErrno); 344 345 if (!fNoClose) 346 { 347 /* Open stdin(0), stdout(1) and stderr(2) as /dev/null. */ 348 int fd = open("/dev/null", O_RDWR); 349 if (fd == -1) /* paranoia */ 350 { 351 close(STDIN_FILENO); 352 close(STDOUT_FILENO); 353 close(STDERR_FILENO); 354 fd = open("/dev/null", O_RDWR); 355 } 356 if (fd != -1) 357 { 358 dup2(fd, STDIN_FILENO); 359 dup2(fd, STDOUT_FILENO); 360 dup2(fd, STDERR_FILENO); 361 if (fd > 2) 362 close(fd); 363 } 364 } 365 366 if (!fNoChDir) 367 chdir("/"); 368 369 /* Second fork to lose session leader status. */ 370 pid = fork(); 371 if (pid == -1) 372 return RTErrConvertFromErrno(errno); 373 if (pid != 0) 374 { 375 /* Write the pid file, this is done in the parent, before exiting. */ 376 if (fdPidfile != -1) 377 { 378 char szBuf[256]; 379 size_t cbPid = RTStrPrintf(szBuf, sizeof(szBuf), "%d\n", pid); 380 write(fdPidfile, szBuf, cbPid); 381 close(fdPidfile); 382 } 383 exit(0); 384 } 385 386 return VINF_SUCCESS; 387 } 388
Note:
See TracChangeset
for help on using the changeset viewer.