Changeset 102062 in vbox for trunk/src/libs/xpcom18a4/ipc/ipcd
- Timestamp:
- Nov 10, 2023 1:27:03 PM (15 months ago)
- Location:
- trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcClient.cpp
r101933 r102062 35 35 * 36 36 * ***** END LICENSE BLOCK ***** */ 37 38 #include "ipcLog.h" 37 #define LOG_GROUP LOG_GROUP_IPC 38 #include <iprt/assert.h> 39 #include <iprt/errcore.h> 40 #include <iprt/poll.h> 41 #include <VBox/log.h> 42 39 43 #include "ipcClient.h" 40 44 #include "ipcMessage.h" … … 42 46 #include "ipcm.h" 43 47 44 #if defined(XP_UNIX) || defined(XP_OS2)45 #include "prio.h"46 #endif47 48 48 PRUint32 ipcClient::gLastID = 0; 49 49 … … 55 55 // 56 56 void 57 ipcClient::Init( )57 ipcClient::Init(uint32_t idPoll, RTSOCKET hSock) 58 58 { 59 59 mID = ++gLastID; … … 61 61 // every client must be able to handle IPCM messages. 62 62 mTargets.Append(IPCM_TARGET); 63 64 m_hSock = hSock; 65 m_idPoll = idPoll; 66 m_fUsed = true; 63 67 64 68 // although it is tempting to fire off the NotifyClientUp event at this … … 73 77 ipcClient::Finalize() 74 78 { 79 RTSocketClose(m_hSock); 80 m_hSock = NIL_RTSOCKET; 81 75 82 IPC_NotifyClientDown(this); 76 83 … … 78 85 mTargets.DeleteAll(); 79 86 80 #if defined(XP_UNIX) || defined(XP_OS2)81 87 mInMsg.Reset(); 82 88 mOutMsgQ.DeleteAll(); 83 #endif 89 m_fUsed = false; 84 90 } 85 91 … … 87 93 ipcClient::AddName(const char *name) 88 94 { 89 L OG(("adding client name: %s\n", name));95 LogFlowFunc(("adding client name: %s\n", name)); 90 96 91 97 if (HasName(name)) … … 98 104 ipcClient::DelName(const char *name) 99 105 { 100 L OG(("deleting client name: %s\n", name));106 LogFlowFunc(("deleting client name: %s\n", name)); 101 107 102 108 return mNames.FindAndDelete(name); … … 106 112 ipcClient::AddTarget(const nsID &target) 107 113 { 108 L OG(("adding client target\n"));114 LogFlowFunc(("adding client target\n")); 109 115 110 116 if (HasTarget(target)) … … 117 123 ipcClient::DelTarget(const nsID &target) 118 124 { 119 L OG(("deleting client target\n"));125 LogFlowFunc(("deleting client target\n")); 120 126 121 127 // … … 128 134 } 129 135 130 #if defined(XP_UNIX) || defined(XP_OS2)131 132 136 // 133 137 // called to process a client socket 134 138 // 135 139 // params: 136 // fd - the client socket137 140 // poll_flags - the state of the client socket 138 141 // … … 143 146 // 144 147 int 145 ipcClient::Process( PRFileDesc *fd, int inFlags)146 { 147 if (inFlags & (PR_POLL_ERR | PR_POLL_HUP |148 PR_POLL_EXCEPT | PR_POLL_NVAL)){149 L OG(("client socket appears to have closed\n"));148 ipcClient::Process(uint32_t inFlags) 149 { 150 if (inFlags & RTPOLL_EVT_ERROR) 151 { 152 LogFlowFunc(("client socket appears to have closed\n")); 150 153 return 0; 151 154 } 152 155 153 156 // expect to wait for more data 154 int outFlags = PR_POLL_READ; 155 156 if (inFlags & PR_POLL_READ) { 157 LOG(("client socket is now readable\n")); 158 159 char buf[1024]; // XXX make this larger? 160 PRInt32 n; 161 162 // find out how much data is available for reading... 163 // n = PR_Available(fd); 164 165 n = PR_Read(fd, buf, sizeof(buf)); 166 if (n <= 0) 157 int outFlags = RTPOLL_EVT_READ; 158 159 if (inFlags & RTPOLL_EVT_READ) { 160 LogFlowFunc(("client socket is now readable\n")); 161 162 char buf[_1K]; 163 size_t cbRead = 0; 164 int vrc = RTSocketReadNB(m_hSock, &buf[0], sizeof(buf), &cbRead); 165 Assert(vrc != VINF_TRY_AGAIN); 166 167 if (RT_FAILURE(vrc) || cbRead == 0) 167 168 return 0; // cancel connection 168 169 169 170 const char *ptr = buf; 170 while (n) { 171 while (cbRead) 172 { 171 173 PRUint32 nread; 172 174 PRBool complete; 173 175 174 if (mInMsg.ReadFrom(ptr, PRUint32( n), &nread, &complete) == PR_FAILURE) {175 L OG(("message appears to be malformed; dropping client connection\n"));176 if (mInMsg.ReadFrom(ptr, PRUint32(cbRead), &nread, &complete) == PR_FAILURE) { 177 LogFlowFunc(("message appears to be malformed; dropping client connection\n")); 176 178 return 0; 177 179 } 178 180 179 if (complete) { 181 if (complete) 182 { 180 183 IPC_DispatchMsg(this, &mInMsg); 181 184 mInMsg.Reset(); 182 185 } 183 186 184 n-= nread;185 ptr += nread;186 } 187 } 188 189 if (inFlags & PR_POLL_WRITE) {190 L OG(("client socket is now writable\n"));187 cbRead -= nread; 188 ptr += nread; 189 } 190 } 191 192 if (inFlags & RTPOLL_EVT_WRITE) { 193 LogFlowFunc(("client socket is now writable\n")); 191 194 192 195 if (mOutMsgQ.First()) 193 WriteMsgs( fd);196 WriteMsgs(); 194 197 } 195 198 196 199 if (mOutMsgQ.First()) 197 outFlags |= PR_POLL_WRITE;200 outFlags |= RTPOLL_EVT_WRITE; 198 201 199 202 return outFlags; … … 204 207 // 205 208 int 206 ipcClient::WriteMsgs(PRFileDesc *fd) 207 { 208 while (mOutMsgQ.First()) { 209 ipcClient::WriteMsgs() 210 { 211 while (mOutMsgQ.First()) 212 { 209 213 const char *buf = (const char *) mOutMsgQ.First()->MsgBuf(); 210 214 PRInt32 bufLen = (PRInt32) mOutMsgQ.First()->MsgLen(); 211 215 212 if (mSendOffset) { 216 if (mSendOffset) 217 { 213 218 buf += mSendOffset; 214 219 bufLen -= mSendOffset; 215 220 } 216 221 217 PRInt32 nw = PR_Write(fd, buf, bufLen); 218 if (nw <= 0) 222 size_t cbWritten = 0; 223 int vrc = RTSocketWriteNB(m_hSock, buf, bufLen, &cbWritten); 224 if (vrc == VINF_SUCCESS) 225 { /* likely */ Assert(cbWritten > 0); } 226 else 227 { 228 Assert( RT_FAILURE(vrc) 229 || (vrc == VINF_TRY_AGAIN && cbWritten == 0)); 219 230 break; 220 221 LOG(("wrote %d bytes\n", nw)); 222 223 if (nw == bufLen) { 231 } 232 233 LogFlowFunc(("wrote %d bytes\n", cbWritten)); 234 235 if (cbWritten == bufLen) 236 { 224 237 mOutMsgQ.DeleteFirst(); 225 238 mSendOffset = 0; 226 239 } 227 240 else 228 mSendOffset += nw;241 mSendOffset += cbWritten; 229 242 } 230 243 … … 232 245 } 233 246 234 #endif -
trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcClient.h
r7029 r102062 39 39 #define ipcClientUnix_h__ 40 40 41 #include "prio.h" 41 #include <iprt/socket.h> 42 42 43 #include "ipcMessageQ.h" 43 44 #include "ipcStringList.h" 44 45 #include "ipcIDList.h" 45 46 #ifdef XP_WIN47 #include <windows.h>48 #endif49 46 50 47 //----------------------------------------------------------------------------- … … 59 56 { 60 57 public: 61 void Init(); 58 bool m_fUsed; 59 uint32_t m_idPoll; 60 uint32_t m_fPollEvts; 61 62 void Init(uint32_t idPoll, RTSOCKET hSock); 62 63 void Finalize(); 63 64 … … 82 83 PRBool GetExpectsSyncReply() const { return mExpectsSyncReply; } 83 84 84 #ifdef XP_WIN85 PRUint32 PID() const { return mPID; }86 void SetPID(PRUint32 pid) { mPID = pid; }87 88 HWND Hwnd() const { return mHwnd; }89 void SetHwnd(HWND hwnd) { mHwnd = hwnd; }90 #endif91 92 #if defined(XP_UNIX) || defined(XP_OS2)93 85 // 94 86 // called to process a client file descriptor. the value of pollFlags … … 96 88 // 97 89 // returns: 98 // 0 - to cancel client connection99 // PR_POLL_READ - to poll for a readable socket100 // PR_POLL_WRITE - to poll for a writable socket101 // (both flags) - to poll for either a readable or writable socket90 // 0 - to cancel client connection 91 // RTPOLL_EVT_READ - to poll for a readable socket 92 // RTPOLL_EVT_WRITE - to poll for a writable socket 93 // (both flags) - to poll for either a readable or writable socket 102 94 // 103 95 // the socket is non-blocking. 104 96 // 105 int Process( PRFileDesc *sockFD, int pollFlags);97 int Process(uint32_t pollFlags); 106 98 107 99 // … … 110 102 // 111 103 void EnqueueOutboundMsg(ipcMessage *msg) { mOutMsgQ.Append(msg); } 112 #endif113 104 114 105 private: … … 120 111 PRBool mExpectsSyncReply; 121 112 122 #ifdef XP_WIN123 // on windows, we store the PID of the client process to help us determine124 // the client from which a message originated. each message has the PID125 // encoded in it.126 PRUint32 mPID;127 128 // the hwnd of the client's message window.129 HWND mHwnd;130 #endif131 132 #if defined(XP_UNIX) || defined(XP_OS2)133 113 ipcMessage mInMsg; // buffer for incoming message 134 114 ipcMessageQ mOutMsgQ; // outgoing message queue … … 137 117 PRUint32 mSendOffset; 138 118 119 /** Client socket. */ 120 RTSOCKET m_hSock; 121 139 122 // utility function for writing out messages. 140 int WriteMsgs(PRFileDesc *fd); 141 #endif 123 int WriteMsgs(); 142 124 }; 143 125 -
trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcdUnix.cpp
r102047 r102062 35 35 * 36 36 * ***** END LICENSE BLOCK ***** */ 37 #define LOG_GROUP LOG_GROUP_IPC 38 #include <iprt/assert.h> 39 #include <iprt/errcore.h> 40 #include <iprt/initterm.h> 41 #include <iprt/getopt.h> 42 #include <iprt/message.h> 43 #include <iprt/poll.h> 44 #include <iprt/socket.h> 45 #include <iprt/string.h> 46 #include <VBox/log.h> 37 47 38 48 #include <sys/types.h> 39 49 #include <sys/stat.h> 50 #include <sys/resource.h> 51 #include <sys/socket.h> 52 #include <sys/un.h> 40 53 #include <unistd.h> 41 54 #include <fcntl.h> … … 44 57 #include <stdlib.h> 45 58 #include <string.h> 46 47 #if defined(VBOX) && !defined(XP_OS2) 48 # include <sys/resource.h> 49 # include <errno.h> 50 #endif 51 52 #include <iprt/initterm.h> 53 #include <iprt/getopt.h> 54 #include <iprt/message.h> 55 56 #include "prio.h" 57 #include "prerror.h" 58 #include "prthread.h" 59 #include "prinrval.h" 59 #include <errno.h> 60 60 61 #include "plstr.h" 61 62 #include "prprf.h" 62 63 63 64 #include "ipcConfig.h" 64 #include "ipcLog.h"65 65 #include "ipcMessage.h" 66 66 #include "ipcClient.h" … … 214 214 static Status InitDaemonDir(const char *socketPath) 215 215 { 216 L OG(("InitDaemonDir [sock=%s]\n", socketPath));217 218 char *baseDir = PL_strdup(socketPath);216 LogFlowFunc(("InitDaemonDir [sock=%s]\n", socketPath)); 217 218 char *baseDir = RTStrDup(socketPath); 219 219 220 220 // … … 232 232 Status status = AcquireDaemonLock(baseDir); 233 233 234 PL_strfree(baseDir);234 RTStrFree(baseDir); 235 235 236 236 if (status == EOk) { … … 243 243 static void ShutdownDaemonDir() 244 244 { 245 L OG(("ShutdownDaemonDir\n"));245 LogFlowFunc(("ShutdownDaemonDir\n")); 246 246 247 247 // deleting directory and files underneath it allows another process … … 274 274 // ipcPollList. 275 275 // 276 static ipcClient ipcClientArray[IPC_MAX_CLIENTS + 1]; 277 278 // 279 // element 0 contains the "server socket" 280 // 281 static PRPollDesc ipcPollList[IPC_MAX_CLIENTS + 1]; 282 283 //----------------------------------------------------------------------------- 284 285 static int AddClient(PRFileDesc *fd) 276 static ipcClient ipcClientArray[IPC_MAX_CLIENTS]; 277 278 static RTPOLLSET g_hPollSet = NIL_RTPOLLSET; 279 280 //----------------------------------------------------------------------------- 281 282 static int AddClient(RTPOLLSET hPollSet, RTSOCKET hSock) 286 283 { 287 284 if (ipcClientCount == IPC_MAX_CLIENTS) { 288 L OG(("reached maximum client limit\n"));285 LogFlowFunc(("reached maximum client limit\n")); 289 286 return -1; 290 287 } 291 288 292 int pollCount = ipcClientCount + 1; 293 294 ipcClientArray[pollCount].Init(); 295 296 ipcPollList[pollCount].fd = fd; 297 ipcPollList[pollCount].in_flags = PR_POLL_READ; 298 ipcPollList[pollCount].out_flags = 0; 299 300 ++ipcClientCount; 301 return 0; 302 } 303 304 static int RemoveClient(int clientIndex) 305 { 306 PRPollDesc *pd = &ipcPollList[clientIndex]; 307 308 PR_Close(pd->fd); 309 310 ipcClientArray[clientIndex].Finalize(); 311 312 // 313 // keep the clients and poll_fds contiguous; move the last one into 314 // the spot held by the one that is going away. 315 // 316 int toIndex = clientIndex; 317 int fromIndex = ipcClientCount; 318 if (fromIndex != toIndex) { 319 memcpy(&ipcClientArray[toIndex], &ipcClientArray[fromIndex], sizeof(ipcClient)); 320 memcpy(&ipcPollList[toIndex], &ipcPollList[fromIndex], sizeof(PRPollDesc)); 321 } 322 323 // 324 // zero out the old entries. 325 // 326 memset(&ipcClientArray[fromIndex], 0, sizeof(ipcClient)); 327 memset(&ipcPollList[fromIndex], 0, sizeof(PRPollDesc)); 328 289 /* Find an unused client entry. */ 290 for (uint32_t i = 0; i < RT_ELEMENTS(ipcClientArray); i++) 291 { 292 if (!ipcClientArray[i].m_fUsed) 293 { 294 ipcClientArray[i].Init(i, hSock); 295 ipcClientArray[i].m_fPollEvts = RTPOLL_EVT_READ; 296 int vrc = RTPollSetAddSocket(hPollSet, hSock, RTPOLL_EVT_READ, i); 297 if (RT_SUCCESS(vrc)) 298 { 299 ipcClientCount++; 300 return 0; 301 } 302 303 ipcClientArray[i].Finalize(); 304 break; 305 } 306 } 307 308 /* Failed to find or set up the IPC client state. */ 309 return -1; 310 } 311 312 static int RemoveClient(RTPOLLSET hPollSet, uint32_t idClient) 313 { 314 int vrc = RTPollSetRemove(hPollSet, idClient); 315 AssertRC(vrc); RT_NOREF(vrc); 316 317 ipcClientArray[idClient].Finalize(); 329 318 --ipcClientCount; 330 319 return 0; … … 333 322 //----------------------------------------------------------------------------- 334 323 335 static void PollLoop(PRFileDesc *listenFD) 336 { 337 // the first element of ipcClientArray is unused. 338 memset(ipcClientArray, 0, sizeof(ipcClientArray)); 339 ipcClients = ipcClientArray + 1; 340 ipcClientCount = 0; 341 342 ipcPollList[0].fd = listenFD; 343 ipcPollList[0].in_flags = PR_POLL_EXCEPT | PR_POLL_READ; 344 345 while (1) { 346 PRInt32 rv; 347 PRIntn i; 348 349 int pollCount = ipcClientCount + 1; 350 351 ipcPollList[0].out_flags = 0; 352 353 // 354 // poll 355 // 356 // timeout after 5 minutes. if no connections after timeout, then 357 // exit. this timeout ensures that we don't stay resident when no 358 // clients are interested in connecting after spawning the daemon. 359 // 360 // XXX add #define for timeout value 361 // 362 LOG(("calling PR_Poll [pollCount=%d]\n", pollCount)); 363 rv = PR_Poll(ipcPollList, pollCount, PR_SecondsToInterval(60 * 5)); 364 if (rv == -1) { 365 LOG(("PR_Poll failed [%d]\n", PR_GetError())); 366 return; 367 } 368 369 if (rv > 0) { 370 // 371 // process clients that are ready 372 // 373 for (i = 1; i < pollCount; ++i) { 374 if (ipcPollList[i].out_flags != 0) { 375 ipcPollList[i].in_flags = 376 ipcClientArray[i].Process(ipcPollList[i].fd, 377 ipcPollList[i].out_flags); 378 ipcPollList[i].out_flags = 0; 324 static void PollLoop(RTPOLLSET hPollSet, int fdListen) 325 { 326 ipcClients = ipcClientArray; 327 328 for (;;) 329 { 330 LogFlowFunc(("Polling [ipcClientCount=%d]\n", ipcClientCount)); 331 uint32_t idPoll = 0; 332 uint32_t fEvents = 0; 333 int vrc = RTPoll(hPollSet, 5 * RT_MS_1MIN, &fEvents, &idPoll); 334 if (RT_SUCCESS(vrc)) 335 { /* likely */ } 336 else if (vrc == VERR_TIMEOUT) 337 { 338 /* Shutdown if no clients. */ 339 if (ipcClientCount == 0) 340 { 341 LogFlowFunc(("shutting down\n")); 342 break; 343 } 344 345 continue; 346 } 347 else 348 { 349 LogFlowFunc(("Polling failed with %Rrc\n", vrc)); 350 break; 351 } 352 353 if (idPoll == UINT32_MAX - 1) 354 { 355 Assert(fEvents & RTPOLL_EVT_READ); 356 LogFlowFunc(("Got new connection\n")); 357 358 int fdClient = accept(fdListen, NULL, NULL); 359 if (fdClient == -1) 360 { 361 /* ignore this error... perhaps the client disconnected. */ 362 LogFlowFunc(("accept() failed [%d]\n", errno)); 363 } 364 else 365 { 366 RTSOCKET hSock; 367 vrc = RTSocketFromNative(&hSock, fdClient); 368 if (RT_SUCCESS(vrc)) 369 { 370 if (AddClient(hPollSet, hSock) != 0) 371 RTSocketClose(hSock); 379 372 } 380 } 381 382 // 383 // cleanup any dead clients (indicated by a zero in_flags) 384 // 385 for (i = pollCount - 1; i >= 1; --i) { 386 if (ipcPollList[i].in_flags == 0) 387 RemoveClient(i); 388 } 389 390 // 391 // check for new connection 392 // 393 if (ipcPollList[0].out_flags & PR_POLL_READ) { 394 LOG(("got new connection\n")); 395 396 PRNetAddr clientAddr; 397 memset(&clientAddr, 0, sizeof(clientAddr)); 398 PRFileDesc *clientFD; 399 400 // @todo : We need to handle errors from accept() especially something like 401 // EMFILE, which happens when we run out of file descriptors. 402 // and puts XPCOMIPCD in a poll/accept endless loop! 403 clientFD = PR_Accept(listenFD, &clientAddr, PR_INTERVAL_NO_WAIT); 404 if (clientFD == NULL) { 405 // ignore this error... perhaps the client disconnected. 406 LOG(("PR_Accept failed [%d]\n", PR_GetError())); 373 else 374 { 375 LogFlowFunc(("RTSocketFromNative(, %d) -> %Rrc\n", fdClient, vrc)); 376 close(fdClient); 407 377 } 408 else { 409 // make socket non-blocking 410 PRSocketOptionData opt; 411 opt.option = PR_SockOpt_Nonblocking; 412 opt.value.non_blocking = PR_TRUE; 413 PR_SetSocketOption(clientFD, &opt); 414 415 if (AddClient(clientFD) != 0) 416 PR_Close(clientFD); 417 } 418 } 419 } 420 421 // 422 // shutdown if no clients 423 // 424 if (ipcClientCount == 0) { 425 LOG(("shutting down\n")); 426 break; 378 } 379 } 380 else 381 { 382 uint32_t fNewFlags = ipcClientArray[idPoll].Process(fEvents); 383 if (!fNewFlags) 384 { 385 /* Cleanup dead client. */ 386 RemoveClient(hPollSet, idPoll); 387 } 388 else if (ipcClientArray[idPoll].m_fPollEvts != fNewFlags) 389 { 390 /* Change flags. */ 391 vrc = RTPollSetEventsChange(hPollSet, idPoll, fNewFlags); 392 AssertRC(vrc); 393 ipcClientArray[idPoll].m_fPollEvts = fNewFlags; 394 } 427 395 } 428 396 } … … 434 402 IPC_PlatformSendMsg(ipcClient *client, ipcMessage *msg) 435 403 { 436 L OG(("IPC_PlatformSendMsg\n"));404 LogFlowFunc(("IPC_PlatformSendMsg\n")); 437 405 438 406 // … … 443 411 // 444 412 // since our Process method may have already been called, we must ensure 445 // that the PR_POLL_WRITE flag is set. 446 // 447 int clientIndex = client - ipcClientArray; 448 ipcPollList[clientIndex].in_flags |= PR_POLL_WRITE; 413 // that the RTPOLL_EVT_WRITE flag is set. 414 // 415 if (!(client->m_fPollEvts & RTPOLL_EVT_WRITE)) 416 { 417 client->m_fPollEvts |= RTPOLL_EVT_WRITE; 418 int vrc = RTPollSetEventsChange(g_hPollSet, client->m_idPoll, client->m_fPollEvts); 419 AssertRC(vrc); 420 } 449 421 450 422 return PR_SUCCESS; … … 455 427 int main(int argc, char **argv) 456 428 { 457 PRFileDesc *listenFD = NULL;458 PRNetAddr addr;459 460 429 /* Set up the runtime without loading the support driver. */ 461 430 int vrc = RTR3InitExe(argc, &argv, 0); … … 506 475 umask(0077); 507 476 508 IPC_InitLog("###"); 509 510 LOG(("daemon started...\n")); 477 LogFlowFunc(("daemon started...\n")); 511 478 512 479 //XXX uncomment these lines to test slow starting daemon 513 480 //IPC_Sleep(2); 514 481 482 struct sockaddr_un addr; 483 memset(&addr, 0, sizeof(addr)); 484 addr.sun_family = AF_UNIX; 485 515 486 // set socket address 516 addr.local.family = PR_AF_LOCAL;517 487 if (!pszSocketPath) 518 IPC_GetDefaultSocketPath(addr. local.path, sizeof(addr.local.path));488 IPC_GetDefaultSocketPath(addr.sun_path, sizeof(addr.sun_path)); 519 489 else 520 PL_strncpyz(addr. local.path, pszSocketPath, sizeof(addr.local.path));490 PL_strncpyz(addr.sun_path, pszSocketPath, sizeof(addr.sun_path)); 521 491 522 492 #ifdef IPC_USE_FILE_LOCK 523 Status status = InitDaemonDir(addr. local.path);493 Status status = InitDaemonDir(addr.sun_path); 524 494 if (status != EOk) { 525 495 if (status == ELockFileLock) { 526 L OG(("Another daemon is already running, exiting.\n"));496 LogFlowFunc(("Another daemon is already running, exiting.\n")); 527 497 // send a signal to the blocked parent to indicate success 528 498 IPC_NotifyParent(uStartupPipeFd); … … 530 500 } 531 501 else { 532 L OG(("InitDaemonDir failed (status=%d)\n", status));502 LogFlowFunc(("InitDaemonDir failed (status=%d)\n", status)); 533 503 // don't notify the parent to cause it to fail in PR_Read() after 534 504 // we terminate 535 505 if (status != ELockFileOwner) 536 506 printf("Cannot create a lock file for '%s'.\n" 537 "Check permissions.\n", addr. local.path);507 "Check permissions.\n", addr.sun_path); 538 508 return 0; 539 509 } … … 541 511 #endif 542 512 543 listenFD = PR_OpenTCPSocket(PR_AF_LOCAL); 544 if (!listenFD) { 545 LOG(("PR_OpenTCPSocket failed [%d]\n", PR_GetError())); 546 } 547 else if (PR_Bind(listenFD, &addr) != PR_SUCCESS) { 548 LOG(("PR_Bind failed [%d]\n", PR_GetError())); 549 } 550 else { 551 // Use large backlog, as otherwise local sockets can reject connection 552 // attempts. Usually harmless, but causes an unnecessary start attempt 553 // of IPCD (which will terminate straight away), and the next attempt 554 // usually succeeds. But better avoid unnecessary activities. 555 if (PR_Listen(listenFD, 128) != PR_SUCCESS) { 556 LOG(("PR_Listen failed [%d]\n", PR_GetError())); 557 } 558 else { 559 560 IPC_NotifyParent(uStartupPipeFd); 513 int fdListen = socket(PF_UNIX, SOCK_STREAM, 0); 514 if (fdListen == -1) 515 LogFlowFunc(("socket failed [%d]\n", errno)); 516 else 517 { 518 if (bind(fdListen, (struct sockaddr *)&addr, sizeof(addr)) == 0) 519 { 520 // Use large backlog, as otherwise local sockets can reject connection 521 // attempts. Usually harmless, but causes an unnecessary start attempt 522 // of IPCD (which will terminate straight away), and the next attempt 523 // usually succeeds. But better avoid unnecessary activities. 524 if (listen(fdListen, 128) == 0) 525 { 526 IPC_NotifyParent(uStartupPipeFd); 561 527 562 528 #if defined(VBOX) && !defined(XP_OS2) 563 // Increase the file table size to 10240 or as high as possible. 564 struct rlimit lim; 565 if (getrlimit(RLIMIT_NOFILE, &lim) == 0) 566 { 567 if ( lim.rlim_cur < 10240 568 && lim.rlim_cur < lim.rlim_max) 529 // Increase the file table size to 10240 or as high as possible. 530 struct rlimit lim; 531 if (getrlimit(RLIMIT_NOFILE, &lim) == 0) 569 532 { 570 lim.rlim_cur = lim.rlim_max <= 10240 ? lim.rlim_max : 10240; 571 if (setrlimit(RLIMIT_NOFILE, &lim) == -1) 572 printf("WARNING: failed to increase file descriptor limit. (%d)\n", errno); 533 if ( lim.rlim_cur < 10240 534 && lim.rlim_cur < lim.rlim_max) 535 { 536 lim.rlim_cur = lim.rlim_max <= 10240 ? lim.rlim_max : 10240; 537 if (setrlimit(RLIMIT_NOFILE, &lim) == -1) 538 printf("WARNING: failed to increase file descriptor limit. (%d)\n", errno); 539 } 573 540 } 541 else 542 printf("WARNING: failed to obtain per-process file-descriptor limit (%d).\n", errno); 543 #endif 544 545 RTSOCKET hSockListen; 546 int vrc = RTSocketFromNative(&hSockListen, fdListen); 547 if (RT_SUCCESS(vrc)) 548 { 549 fdListen = (int)RTSocketToNative(hSockListen); 550 551 RTPOLLSET hPollSet = NIL_RTPOLLSET; 552 vrc = RTPollSetCreate(&hPollSet); 553 if (RT_SUCCESS(vrc)) 554 { 555 g_hPollSet = hPollSet; 556 557 vrc = RTPollSetAddSocket(hPollSet, hSockListen, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, UINT32_MAX - 1); 558 if (RT_SUCCESS(vrc)) 559 PollLoop(hPollSet, fdListen); 560 else 561 LogFlowFunc(("RTPollSetCreate() -> %Rrc\n", vrc)); 562 } 563 else 564 LogFlowFunc(("RTPollSetCreate() -> %Rrc\n", vrc)); 565 566 vrc = RTPollSetDestroy(hPollSet); 567 AssertRC(vrc); 568 } 569 else 570 LogFlowFunc(("RTSocketFromNative() -> %Rrc\n", vrc)); 571 572 vrc = RTSocketClose(hSockListen); 573 AssertRC(vrc); 574 fdListen = -1; 574 575 } 575 576 else 576 printf("WARNING: failed to obtain per-process file-descriptor limit (%d).\n", errno); 577 #endif 578 579 PollLoop(listenFD); 580 } 577 LogFlowFunc(("listen failed [%d]\n", errno)); 578 } 579 else 580 LogFlowFunc(("bind failed [%d]\n", errno)); 581 582 LogFlowFunc(("closing socket\n")); 583 if (fdListen != -1) 584 close(fdListen); 581 585 } 582 586 … … 591 595 #endif 592 596 593 if (listenFD) {594 LOG(("closing socket\n"));595 PR_Close(listenFD);596 }597 598 597 return 0; 599 598 }
Note:
See TracChangeset
for help on using the changeset viewer.