Changeset 58319 in vbox
- Timestamp:
- Oct 19, 2015 7:30:29 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 103517
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/localipc-posix.cpp
r58318 r58319 682 682 683 683 /** 684 * Checks if the socket has has a HUP condition .684 * Checks if the socket has has a HUP condition after reading zero bytes. 685 685 * 686 686 * @returns true if HUP, false if no. … … 689 689 static bool rtLocalIpcPosixHasHup(PRTLOCALIPCSESSIONINT pThis) 690 690 { 691 #ifndef RT_OS_OS2 691 int fdNative = RTSocketToNative(pThis->hSocket); 692 693 #if !defined(RT_OS_OS2) && !defined(RT_OS_SOLARIS) 692 694 struct pollfd PollFd; 693 695 RT_ZERO(PollFd); 694 PollFd.fd = RTSocketToNative(pThis->hSocket); 695 PollFd.events = POLLHUP | POLLIN; 696 if (poll(&PollFd, 1, 0) > 0) 697 { 698 if (PollFd.revents & POLLIN) 699 { 700 # ifdef RT_OS_SOLARIS 701 /* Solaris doesn't seem to set POLLHUP for disconnected unix domain 702 sockets. So, we have to do extra stupid work here to detect it. */ 703 uint8_t bDummy; 704 ssize_t rcSend = send(PollFd.fd, &bDummy, 0, MSG_DONTWAIT); 705 if (rcSend < 0 && (errno == EPIPE || errno == ECONNRESET)) 706 return true; 707 AssertMsg(rcSend == 0, ("rcSend=%zd errno=%d\n", rcSend, errno)); 708 # endif 709 return false; 710 } 711 Assert(PollFd.revents != 0); 712 return true; 713 } 714 #else /* RT_OS_OS2 */ 715 /* No native poll, do zero byte send to check for EPIPE. */ 696 PollFd.fd = fdNative; 697 PollFd.events = POLLHUP; 698 if (poll(&PollFd, 1, 0) <= 0) 699 return false; 700 if (!(PollFd.revents & (POLLHUP | POLLERR))) 701 return false; 702 #else /* RT_OS_OS2 || RT_OS_SOLARIS */ 703 /* 704 * OS/2: No native poll, do zero byte send to check for EPIPE. 705 * Solaris: We don't get POLLHUP. 706 */ 716 707 uint8_t bDummy; 717 ssize_t rcSend = send(PollFd.fd, &bDummy, 0, 0); 718 if (rcSend < 0 && (errno == EPIPE || errno == ECONNRESET)) 719 return true; 720 #endif /* RT_OS_OS2 */ 721 return false; 708 ssize_t rcSend = send(fdNative, &bDummy, 0, 0); 709 if (rcSend >= 0 || (errno != EPIPE && errno != ECONNRESET)) 710 return false; 711 #endif /* RT_OS_OS2 || RT_OS_SOLARIS */ 712 713 /* 714 * We've established EPIPE. Now make sure there aren't any last bytes to 715 * read that came in between the recv made by the caller and the disconnect. 716 */ 717 uint8_t bPeek; 718 ssize_t rcRecv = recv(fdNative, &bPeek, 1, MSG_DONTWAIT | MSG_PEEK); 719 return rcRecv <= 0; 722 720 } 723 721 … … 982 980 if (cFds >= 1) 983 981 { 984 /* Solaris may flag both POLLIN and POLLHUP for pipes when there is more 985 input to read. Also, solaris may give us POLLIN without POLLHUP even 986 if a unix domain socket is already disconnected. So, extra solaris 987 hacks are necessary here in addition to prioritizing POLLIN. */ 988 if (PollFd.revents & POLLIN) 982 /* Linux 4.2.2 sets both POLLIN and POLLHUP when the pipe is 983 broken and but no more data to read. Google hints at NetBSD 984 returning more sane values (POLLIN till no more data, then 985 POLLHUP). Solairs OTOH, doesn't ever seem to return POLLHUP. */ 986 fEvents = RTPOLL_EVT_READ; 987 if ( (PollFd.revents & (POLLHUP | POLLERR)) 988 && !(PollFd.revents & POLLIN)) 989 fEvents = RTPOLL_EVT_ERROR; 990 # if defined(RT_OS_SOLARIS) 991 else if (PollFd.revents & POLLIN) 992 # else 993 else if ((PollFd.revents & (POLLIN | POLLHUP)) == (POLLIN | POLLHUP)) 994 # endif 989 995 { 990 fEvents = RTPOLL_EVT_READ; 991 # ifdef RT_OS_SOLARIS /* Same hack as in rtLocalIpcPosixHasHup. */ 992 uint8_t bDummy; 993 ssize_t rcSend = send(PollFd.fd, &bDummy, 0, MSG_DONTWAIT); 994 if (rcSend < 0 && (errno == EPIPE || errno == ECONNRESET)) 996 /* Check if there is actually data available. */ 997 uint8_t bPeek; 998 ssize_t rcRecv = recv(PollFd.fd, &bPeek, 1, MSG_DONTWAIT | MSG_PEEK); 999 if (rcRecv <= 0) 995 1000 fEvents = RTPOLL_EVT_ERROR; 996 else997 AssertMsg(rcSend == 0, ("rcSend=%zd errno=%d\n", rcSend, errno));998 # endif999 1001 } 1000 else1001 fEvents = RTPOLL_EVT_ERROR;1002 1002 rc = VINF_SUCCESS; 1003 1003 }
Note:
See TracChangeset
for help on using the changeset viewer.