Changeset 33044 in vbox for trunk/src/VBox/Runtime/r3/posix/process-posix.cpp
- Timestamp:
- Oct 11, 2010 4:30:54 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 66568
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/process-posix.cpp
r33009 r33044 266 266 AssertPtrReturn(pszExec, VERR_INVALID_POINTER); 267 267 AssertReturn(*pszExec, VERR_INVALID_PARAMETER); 268 AssertReturn(!(fFlags & ~(RTPROC_FLAGS_D AEMONIZE_DEPRECATED | RTPROC_FLAGS_DETACHED | RTPROC_FLAGS_SERVICE)), VERR_INVALID_PARAMETER);268 AssertReturn(!(fFlags & ~(RTPROC_FLAGS_DETACHED | RTPROC_FLAGS_SERVICE)), VERR_INVALID_PARAMETER); 269 269 AssertReturn(!(fFlags & RTPROC_FLAGS_DETACHED) || !phProcess, VERR_INVALID_PARAMETER); 270 270 AssertReturn(hEnv != NIL_RTENV, VERR_INVALID_PARAMETER); … … 346 346 } 347 347 348 /* 349 * Spawn the child. 348 pid_t pid = -1; 349 350 /* 351 * Take care of detaching the process. 350 352 * 351 353 * HACK ALERT! Put the process into a new process group with pgid = pid 352 354 * to make sure it differs from that of the parent process to ensure that 353 * the IPRT waipit call doesn't race anyone (read XPCOM) doing group wide 354 * waits. 355 */ 356 pid_t pid = -1; 355 * the IPRT waitpid call doesn't race anyone (read XPCOM) doing group wide 356 * waits. setsid() includes the setpgid() functionality. 357 * 2010-10-11 XPCOM no longer waits for anything, but it cannot hurt. 358 */ 359 #ifndef RT_OS_OS2 360 if (fFlags & RTPROC_FLAGS_DETACHED) 361 { 362 # ifdef RT_OS_SOLARIS 363 int templateFd = rtSolarisContractPreFork(); 364 if (templateFd == -1) 365 return VERR_OPEN_FAILED; 366 # endif /* RT_OS_SOLARIS */ 367 pid = fork(); 368 if (!pid) 369 { 370 # ifdef RT_OS_SOLARIS 371 rtSolarisContractPostForkChild(templateFd); 372 # endif /* RT_OS_SOLARIS */ 373 setsid(); /* see comment above */ 374 375 pid = -1; 376 /* Child falls through to the actual spawn code below. */ 377 } 378 else 379 { 380 #ifdef RT_OS_SOLARIS 381 rtSolarisContractPostForkParent(templateFd, pid); 382 #endif /* RT_OS_SOLARIS */ 383 if (pid > 0) 384 { 385 /* Must wait for the temporary process to avoid a zombie. */ 386 int status; 387 waitpid(pid, &status, 0); 388 /* Assume that something wasn't found. No detailed info. */ 389 if (status) 390 return VERR_PROCESS_NOT_FOUND; 391 if (phProcess) 392 *phProcess = 0; 393 return VINF_SUCCESS; 394 } 395 return RTErrConvertFromErrno(errno); 396 } 397 } 398 #endif 399 400 /* 401 * Spawn the child. 402 * 403 * Any spawn code MUST not execute any atexit functions if it is for a 404 * detached process. It would lead to running the atexit functions which 405 * make only sense for the parent. libORBit e.g. gets confused by multiple 406 * execution. Remember, there was only a fork() so far, and until exec() 407 * is successfully run there is nothing which would prevent doing anything 408 * silly with the (duplicated) file descriptors. 409 */ 357 410 #ifdef HAVE_POSIX_SPAWN 358 411 /** @todo OS/2: implement DETACHED (BACKGROUND stuff), see VbglR3Daemonize. */ 359 /** @todo Try do the detach thing with posix spawn. */ 360 if ( !(fFlags & (RTPROC_FLAGS_DAEMONIZE_DEPRECATED | RTPROC_FLAGS_DETACHED)) 361 && uid == ~(uid_t)0 362 && gid == ~(gid_t)0 363 ) 412 if ( uid == ~(uid_t)0 413 && gid == ~(gid_t)0) 364 414 { 365 415 /* Spawn attributes. */ … … 428 478 if (!rc) 429 479 { 480 /* For a detached process this happens in the temp process, so 481 * it's not worth doing anything as this process must exit. */ 482 if (fFlags & RTPROC_FLAGS_DETACHED) 483 _Exit(0); 430 484 if (phProcess) 431 485 *phProcess = pid; … … 433 487 } 434 488 } 489 /* For a detached process this happens in the temp process, so 490 * it's not worth doing anything as this process must exit. */ 491 if (fFlags & RTPROC_FLAGS_DETACHED) 492 _Exit(124); 435 493 } 436 494 else … … 448 506 rtSolarisContractPostForkChild(templateFd); 449 507 #endif /* RT_OS_SOLARIS */ 450 setpgid(0, 0); /* see comment above */ 508 if (!(fFlags & RTPROC_FLAGS_DETACHED)) 509 setpgid(0, 0); /* see comment above */ 451 510 452 511 /* … … 457 516 { 458 517 if (setgid(gid)) 459 exit(126); 518 { 519 if (fFlags & RTPROC_FLAGS_DETACHED) 520 _Exit(126); 521 else 522 exit(126); 523 } 460 524 } 461 525 … … 463 527 { 464 528 if (setuid(uid)) 465 exit(126); 529 { 530 if (fFlags & RTPROC_FLAGS_DETACHED) 531 _Exit(126); 532 else 533 exit(126); 534 } 466 535 } 467 536 #endif … … 479 548 int rc2 = dup2(fd, i); 480 549 if (rc2 != i) 481 exit(125); 550 { 551 if (fFlags & RTPROC_FLAGS_DETACHED) 552 _Exit(125); 553 else 554 exit(125); 555 } 482 556 for (int j = i + 1; j < 3; j++) 483 557 if (aStdFds[j] == fd) … … 492 566 493 567 /* 494 * Daemonize the process if requested.495 */496 if (fFlags & (RTPROC_FLAGS_DAEMONIZE_DEPRECATED | RTPROC_FLAGS_DETACHED))497 {498 rc = RTProcDaemonizeUsingFork(true /*fNoChDir*/,499 !(fFlags & RTPROC_FLAGS_DAEMONIZE_DEPRECATED) /*fNoClose*/,500 NULL /* pszPidFile */);501 if (RT_FAILURE(rc))502 {503 /* parent */504 AssertReleaseMsgFailed(("RTProcDaemonize returns %Rrc errno=%d\n", rc, errno));505 exit(127);506 }507 /* daemonized child */508 }509 510 /*511 568 * Finally, execute the requested program. 512 569 */ … … 520 577 RTAssertMsg2Weak("execve returns %d errno=%d\n", rc, errno); 521 578 RTAssertReleasePanic(); 522 exit(127); 579 if (fFlags & RTPROC_FLAGS_DETACHED) 580 _Exit(127); 581 else 582 exit(127); 523 583 } 524 584 #ifdef RT_OS_SOLARIS … … 527 587 if (pid > 0) 528 588 { 589 /* For a detached process this happens in the temp process, so 590 * it's not worth doing anything as this process must exit. */ 591 if (fFlags & RTPROC_FLAGS_DETACHED) 592 _Exit(0); 529 593 if (phProcess) 530 594 *phProcess = pid; 531 else if (fFlags & (RTPROC_FLAGS_DAEMONIZE_DEPRECATED | RTPROC_FLAGS_DETACHED))532 {533 /* If the process is detached straight away wait for the534 * intermediate process to exit (it should do that quickly)535 * if the caller didn't want to know the PID. If it wants the536 * PID it's his job to wait for it or he gets a zombie. */537 waitpid(pid, NULL, 0);538 }539 595 return VINF_SUCCESS; 540 596 } 541 rc = errno; 542 } 543 597 /* For a detached process this happens in the temp process, so 598 * it's not worth doing anything as this process must exit. */ 599 if (fFlags & RTPROC_FLAGS_DETACHED) 600 _Exit(124); 601 return RTErrConvertFromErrno(errno); 602 } 544 603 545 604 return VERR_NOT_IMPLEMENTED;
Note:
See TracChangeset
for help on using the changeset viewer.