Changeset 102047 in vbox for trunk/src/libs/xpcom18a4/ipc
- Timestamp:
- Nov 9, 2023 6:27:01 PM (15 months ago)
- Location:
- trunk/src/libs/xpcom18a4/ipc/ipcd
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp
r101966 r102047 56 56 57 57 #include "prio.h" 58 #include "prproces.h"59 58 60 59 #include <iprt/asm.h> 61 60 #include <iprt/critsect.h> 61 #include <iprt/env.h> 62 #include <iprt/message.h> 63 #include <iprt/pipe.h> 64 #include <iprt/process.h> 65 #include <iprt/string.h> 62 66 63 67 /* ------------------------------------------------------------------------- */ … … 1226 1230 IPC_SpawnDaemon(const char *path) 1227 1231 { 1228 PRFileDesc *readable = nsnull, *writable = nsnull; 1229 PRProcessAttr *attr = nsnull; 1230 nsresult rv = NS_ERROR_FAILURE; 1231 PRFileDesc *devNull; 1232 char *const argv[] = { (char *const) path, nsnull }; 1233 char c; 1234 1235 // setup an anonymous pipe that we can use to determine when the daemon 1236 // process has started up. the daemon will write a char to the pipe, and 1237 // when we read it, we'll know to proceed with trying to connect to the 1238 // daemon. 1239 1240 if (PR_CreatePipe(&readable, &writable) != PR_SUCCESS) 1241 goto end; 1242 PR_SetFDInheritable(writable, PR_TRUE); 1243 1244 attr = PR_NewProcessAttr(); 1245 if (!attr) 1246 goto end; 1247 1248 if (PR_ProcessAttrSetInheritableFD(attr, writable, IPC_STARTUP_PIPE_NAME) != PR_SUCCESS) 1249 goto end; 1250 1251 devNull = PR_Open("/dev/null", PR_RDWR, 0); 1252 if (!devNull) 1253 goto end; 1254 1255 PR_ProcessAttrSetStdioRedirect(attr, PR_StandardInput, devNull); 1256 PR_ProcessAttrSetStdioRedirect(attr, PR_StandardOutput, devNull); 1257 PR_ProcessAttrSetStdioRedirect(attr, PR_StandardError, devNull); 1258 1259 if (PR_CreateProcessDetached(path, argv, nsnull, attr) != PR_SUCCESS) 1260 goto end; 1261 1262 // Close /dev/null 1263 PR_Close(devNull); 1264 // close the child end of the pipe in order to get notification on unexpected 1265 // child termination instead of being infinitely blocked in PR_Read(). 1266 PR_Close(writable); 1267 writable = nsnull; 1268 1269 if ((PR_Read(readable, &c, 1) != 1) || (c != IPC_STARTUP_PIPE_MAGIC)) 1270 goto end; 1271 1272 rv = NS_OK; 1273 end: 1274 if (readable) 1275 PR_Close(readable); 1276 if (writable) 1277 PR_Close(writable); 1278 if (attr) 1279 PR_DestroyProcessAttr(attr); 1280 return rv; 1232 /* 1233 * Setup an anonymous pipe that we can use to determine when the daemon 1234 * process has started up. the daemon will write a char to the pipe, and 1235 * when we read it, we'll know to proceed with trying to connect to the 1236 * daemon. 1237 */ 1238 RTPIPE hPipeWr = NIL_RTPIPE; 1239 RTPIPE hPipeRd = NIL_RTPIPE; 1240 int vrc = RTPipeCreate(&hPipeRd, &hPipeWr, RTPIPE_C_INHERIT_WRITE); 1241 if (RT_SUCCESS(vrc)) 1242 { 1243 char szPipeInheritFd[32]; RT_ZERO(szPipeInheritFd); 1244 const char *const s_apszArgs[] = { (char *const) path, "--inherit-startup-pipe", &szPipeInheritFd[0], NULL }; 1245 char c; 1246 1247 ssize_t cch = RTStrFormatU32(&szPipeInheritFd[0], sizeof(szPipeInheritFd), 1248 (uint32_t)RTPipeToNative(hPipeWr), 10 /*uiBase*/, 1249 0 /*cchWidth*/, 0 /*cchPrecision*/, 0 /*fFlags*/); 1250 Assert(cch > 0); 1251 1252 RTHANDLE hStdNil; 1253 hStdNil.enmType = RTHANDLETYPE_FILE; 1254 hStdNil.u.hFile = NIL_RTFILE; 1255 1256 vrc = RTProcCreateEx(path, s_apszArgs, RTENV_DEFAULT, 1257 RTPROC_FLAGS_DETACHED, &hStdNil, &hStdNil, &hStdNil, 1258 NULL /* pszAsUser */, NULL /* pszPassword */, NULL /* pExtraData */, 1259 NULL /* phProcess */); 1260 if (RT_SUCCESS(vrc)) 1261 { 1262 vrc = RTPipeClose(hPipeWr); AssertRC(vrc); RT_NOREF(vrc); 1263 hPipeWr = NIL_RTPIPE; 1264 1265 uint8_t ch; 1266 vrc = RTPipeReadBlocking(hPipeRd, &ch, sizeof(ch), NULL /*pcbRead*/); 1267 if ( RT_SUCCESS(vrc) 1268 && ch == IPC_STARTUP_PIPE_MAGIC) 1269 { 1270 RTPipeClose(hPipeRd); 1271 return NS_OK; 1272 } 1273 } 1274 1275 if (hPipeWr != NIL_RTPIPE) 1276 RTPipeClose(hPipeWr); 1277 RTPipeClose(hPipeRd); 1278 } 1279 1280 return NS_ERROR_FAILURE; 1281 1281 } 1282 1282 -
trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcd.cpp
r101996 r102047 47 47 48 48 #include <iprt/assert.h> 49 50 //----------------------------------------------------------------------------- 51 52 void 53 IPC_NotifyParent() 54 { 55 PRFileDesc *fd = PR_GetInheritedFD(IPC_STARTUP_PIPE_NAME); 56 if (fd) { 57 char c = IPC_STARTUP_PIPE_MAGIC; 58 PR_Write(fd, &c, 1); 59 PR_Close(fd); 49 #include <iprt/errcore.h> 50 #include <iprt/pipe.h> 51 #include <VBox/log.h> 52 53 //----------------------------------------------------------------------------- 54 55 void 56 IPC_NotifyParent(uint32_t uPipeFd) 57 { 58 if (uPipeFd != UINT32_MAX) 59 { 60 RTPIPE hPipe = NIL_RTPIPE; 61 int vrc = RTPipeFromNative(&hPipe, (RTHCINTPTR)uPipeFd, RTPIPE_N_WRITE); 62 if (RT_SUCCESS(vrc)) 63 { 64 char c = IPC_STARTUP_PIPE_MAGIC; 65 66 vrc = RTPipeWriteBlocking(hPipe, &c, sizeof(c), NULL /*pcbWritten*/); 67 AssertRC(vrc); RT_NOREF(vrc); 68 69 vrc = RTPipeClose(hPipe); 70 AssertRC(vrc); RT_NOREF(vrc); 71 } 60 72 } 61 73 } … … 110 122 return IPC_PlatformSendMsg(client, msg); 111 123 112 L OG((" no registered message handler\n"));124 Log((" no registered message handler\n")); 113 125 return PR_FAILURE; 114 126 } … … 117 129 IPC_NotifyClientUp(ipcClient *client) 118 130 { 119 L OG(("IPC_NotifyClientUp: clientID=%d\n", client->ID()));131 Log(("IPC_NotifyClientUp: clientID=%d\n", client->ID())); 120 132 121 133 for (int i=0; i<ipcClientCount; ++i) { … … 129 141 IPC_NotifyClientDown(ipcClient *client) 130 142 { 131 L OG(("IPC_NotifyClientDown: clientID=%d\n", client->ID()));143 Log(("IPC_NotifyClientDown: clientID=%d\n", client->ID())); 132 144 133 145 for (int i=0; i<ipcClientCount; ++i) { -
trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcdPrivate.h
r39978 r102047 61 61 // notify parent that it can connect to the daemon. 62 62 // 63 void IPC_NotifyParent( );63 void IPC_NotifyParent(uint32_t uPipeFd); 64 64 65 65 #endif // !ipcdPrivate_h__ -
trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcdUnix.cpp
r101982 r102047 50 50 #endif 51 51 52 #i fdef VBOX53 # include <iprt/initterm.h>54 # endif52 #include <iprt/initterm.h> 53 #include <iprt/getopt.h> 54 #include <iprt/message.h> 55 55 56 56 #include "prio.h" … … 458 458 PRNetAddr addr; 459 459 460 #ifdef VBOX461 460 /* Set up the runtime without loading the support driver. */ 462 RTR3InitExe(argc, &argv, 0); 463 #endif 461 int vrc = RTR3InitExe(argc, &argv, 0); 462 if (RT_FAILURE(vrc)) 463 return RTMsgInitFailure(vrc); 464 465 /* 466 * Parse the command line. 467 */ 468 static RTGETOPTDEF const s_aOptions[] = 469 { 470 { "--inherit-startup-pipe", 'f', RTGETOPT_REQ_UINT32 }, 471 { "--socket-path", 'p', RTGETOPT_REQ_STRING }, 472 }; 473 474 RTGETOPTSTATE State; 475 vrc = RTGetOptInit(&State, argc, argv, &s_aOptions[0], RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); 476 if (RT_FAILURE(vrc)) 477 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOptInit failed: %Rrc", vrc); 478 479 uint32_t uStartupPipeFd = UINT32_MAX; 480 const char *pszSocketPath = NULL; 481 RTGETOPTUNION ValueUnion; 482 int chOpt; 483 while ((chOpt = RTGetOpt(&State, &ValueUnion)) != 0) 484 { 485 switch (chOpt) 486 { 487 case 'f': 488 uStartupPipeFd = ValueUnion.u32; 489 break; 490 case 'p': 491 pszSocketPath = ValueUnion.psz; 492 break; 493 default: 494 return RTGetOptPrintError(chOpt, &ValueUnion); 495 } 496 } 464 497 465 498 // … … 482 515 // set socket address 483 516 addr.local.family = PR_AF_LOCAL; 484 if ( argc < 2)517 if (!pszSocketPath) 485 518 IPC_GetDefaultSocketPath(addr.local.path, sizeof(addr.local.path)); 486 519 else 487 PL_strncpyz(addr.local.path, argv[1], sizeof(addr.local.path));520 PL_strncpyz(addr.local.path, pszSocketPath, sizeof(addr.local.path)); 488 521 489 522 #ifdef IPC_USE_FILE_LOCK … … 493 526 LOG(("Another daemon is already running, exiting.\n")); 494 527 // send a signal to the blocked parent to indicate success 495 IPC_NotifyParent( );528 IPC_NotifyParent(uStartupPipeFd); 496 529 return 0; 497 530 } … … 500 533 // don't notify the parent to cause it to fail in PR_Read() after 501 534 // we terminate 502 #ifdef VBOX503 535 if (status != ELockFileOwner) 504 536 printf("Cannot create a lock file for '%s'.\n" 505 537 "Check permissions.\n", addr.local.path); 506 #endif507 538 return 0; 508 539 } … … 518 549 } 519 550 else { 520 #ifdef VBOX521 551 // Use large backlog, as otherwise local sockets can reject connection 522 552 // attempts. Usually harmless, but causes an unnecessary start attempt … … 524 554 // usually succeeds. But better avoid unnecessary activities. 525 555 if (PR_Listen(listenFD, 128) != PR_SUCCESS) { 526 #else /* !VBOX */527 if (PR_Listen(listenFD, 5) != PR_SUCCESS) {528 #endif /* !VBOX */529 556 LOG(("PR_Listen failed [%d]\n", PR_GetError())); 530 557 } 531 558 else { 532 #ifndef VBOX 533 // redirect all standard file descriptors to /dev/null for 534 // proper daemonizing 535 PR_Close(PR_STDIN); 536 PR_Open("/dev/null", O_RDONLY, 0); 537 PR_Close(PR_STDOUT); 538 PR_Open("/dev/null", O_WRONLY, 0); 539 PR_Close(PR_STDERR); 540 PR_Open("/dev/null", O_WRONLY, 0); 541 #endif 542 543 IPC_NotifyParent(); 559 560 IPC_NotifyParent(uStartupPipeFd); 544 561 545 562 #if defined(VBOX) && !defined(XP_OS2)
Note:
See TracChangeset
for help on using the changeset viewer.