Index: /trunk/include/iprt/localipc.h
===================================================================
--- /trunk/include/iprt/localipc.h	(revision 58294)
+++ /trunk/include/iprt/localipc.h	(revision 58295)
@@ -161,4 +161,21 @@
 
 /**
+ * Receive pending data from the other end of an local IPC session.
+ *
+ * This will not block to wait for data.
+ *
+ * @returns IPRT status code.
+ * @retval  VINF_TRY_AGAIN if no pending data (*pcbRead is set to 0).
+ * @retval  VERR_CANCELLED if a previous operation was cancelled by
+ *          RTLocalIpcSessionCancel (this operation isn't cancellable).
+ *
+ * @param   hSession            The session handle.
+ * @param   pvBuf               Where to store the data.
+ * @param   cbToRead            How much to read (upper limit).
+ * @param   pcbRead             Where to return exactly how much was read.
+ */
+RTDECL(int) RTLocalIpcSessionReadNB(RTLOCALIPCSESSION hSession, void *pvBuf, size_t cbToRead, size_t *pcbRead);
+
+/**
  * Send data to the other end of an local IPC session.
  *
@@ -190,6 +207,6 @@
 
 /**
- * Wait for data to become ready for reading or for the
- * session to be disconnected.
+ * Wait for data to become ready for reading or for the session to be
+ * disconnected.
  *
  * @returns IPRT status code.
@@ -212,6 +229,7 @@
  *
  * Not all methods are cancellable, only those which are specfied
- * returning VERR_CANCELLED. The others are assumed to not be blocking
- * for ever and ever.
+ * returning VERR_CANCELLED.  The others are assumed to not be blocking
+ * for ever and ever.  However, the cancel is sticky, so the session must
+ * basically be trashed (closed) after calling this method.
  *
  * @returns IPRT status code.
Index: /trunk/include/iprt/mangling.h
===================================================================
--- /trunk/include/iprt/mangling.h	(revision 58294)
+++ /trunk/include/iprt/mangling.h	(revision 58295)
@@ -742,4 +742,5 @@
 # define RTLocalIpcSessionCancel                        RT_MANGLER(RTLocalIpcSessionCancel)
 # define RTLocalIpcSessionRead                          RT_MANGLER(RTLocalIpcSessionRead)
+# define RTLocalIpcSessionReadNB                        RT_MANGLER(RTLocalIpcSessionReadNB)
 # define RTLocalIpcSessionWrite                         RT_MANGLER(RTLocalIpcSessionWrite)
 # define RTLocalIpcSessionFlush                         RT_MANGLER(RTLocalIpcSessionFlush)
Index: /trunk/src/VBox/Runtime/r3/posix/localipc-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/localipc-posix.cpp	(revision 58294)
+++ /trunk/src/VBox/Runtime/r3/posix/localipc-posix.cpp	(revision 58295)
@@ -727,4 +727,61 @@
 
 
+RTDECL(int) RTLocalIpcSessionReadNB(RTLOCALIPCSESSION hSession, void *pvBuf, size_t cbToRead, size_t *pcbRead)
+{
+    /*
+     * Validate input.
+     */
+    PRTLOCALIPCSESSIONINT pThis = hSession;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->u32Magic == RTLOCALIPCSESSION_MAGIC, VERR_INVALID_HANDLE);
+
+    /*
+     * Do the job.
+     */
+    rtLocalIpcSessionRetain(pThis);
+
+    int rc = RTCritSectEnter(&pThis->CritSect);
+    if (RT_SUCCESS(rc))
+    {
+        if (pThis->hReadThread == NIL_RTTHREAD)
+        {
+            pThis->hReadThread = RTThreadSelf(); /* not really required, but whatever. */
+
+            for (;;)
+            {
+                if (!pThis->fCancelled)
+                {
+                    rc = RTSocketReadNB(pThis->hSocket, pvBuf, cbToRead, pcbRead);
+
+                    /* Detect broken pipe. */
+                    if (rc == VINF_SUCCESS)
+                    {
+                        if (!pcbRead || *pcbRead)
+                        { /* likely */ }
+                        else if (rtLocalIpcPosixHasHup(pThis))
+                            rc = VERR_BROKEN_PIPE;
+                    }
+                    else if (rc == VERR_NET_CONNECTION_RESET_BY_PEER || rc == VERR_NET_SHUTDOWN)
+                        rc = VERR_BROKEN_PIPE;
+
+                    if (rc == VERR_INTERRUPTED)
+                        continue;
+                }
+                else
+                    rc = VERR_CANCELLED;
+                break;
+            }
+
+            pThis->hReadThread = NIL_RTTHREAD;
+        }
+        int rc2 = RTCritSectLeave(&pThis->CritSect);
+        AssertStmt(RT_SUCCESS(rc2), rc = RT_SUCCESS(rc) ? rc2 : rc);
+    }
+
+    rtLocalIpcSessionRelease(pThis);
+    return rc;
+}
+
+
 RTDECL(int) RTLocalIpcSessionWrite(RTLOCALIPCSESSION hSession, const void *pvBuf, size_t cbToWrite)
 {
Index: /trunk/src/VBox/Runtime/r3/socket.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/socket.cpp	(revision 58294)
+++ /trunk/src/VBox/Runtime/r3/socket.cpp	(revision 58295)
@@ -1220,5 +1220,9 @@
     if (cbRead >= 0)
         *pcbRead = cbRead;
-    else if (errno == EAGAIN)
+    else if (   errno == EAGAIN
+# ifdef EWOULDBLOCK
+             || errno == EWOULDBLOCK
+# endif
+             )
     {
         *pcbRead = 0;
@@ -1272,5 +1276,9 @@
     if (cbWritten >= 0)
         *pcbWritten = cbWritten;
-    else if (errno == EAGAIN)
+    else if (   errno == EAGAIN
+# ifdef EWOULDBLOCK
+             || errno == EWOULDBLOCK
+# endif
+            )
     {
         *pcbWritten = 0;
Index: /trunk/src/VBox/Runtime/testcase/tstRTLocalIpc.cpp
===================================================================
--- /trunk/src/VBox/Runtime/testcase/tstRTLocalIpc.cpp	(revision 58294)
+++ /trunk/src/VBox/Runtime/testcase/tstRTLocalIpc.cpp	(revision 58295)
@@ -92,6 +92,6 @@
     RTTESTI_CHECK_RC_RETV(rc = RTLocalIpcSessionConnect(&hIpcSession, "BasicTest", 0), VERR_FILE_NOT_FOUND);
     if (RT_SUCCESS(rc)) RTLocalIpcSessionClose(hIpcSession);
-    RTTESTI_CHECK_RC(RTLocalIpcServerCancel(hIpcServer), VERR_INVALID_HANDLE);
-    RTTESTI_CHECK_RC(RTLocalIpcServerDestroy(hIpcServer), VERR_INVALID_HANDLE);
+    //RTTESTI_CHECK_RC(RTLocalIpcServerCancel(hIpcServer), VERR_INVALID_HANDLE);  - accessing freed memory, bad idea.
+    //RTTESTI_CHECK_RC(RTLocalIpcServerDestroy(hIpcServer), VERR_INVALID_HANDLE); - accessing freed memory, bad idea.
 }
 
@@ -273,4 +273,10 @@
     RTTESTI_CHECK_RC(RTLocalIpcSessionWaitForData(hClientSession, 0 /*cMsTimeout*/), VERR_TIMEOUT);
     RTTESTI_CHECK_RC(RTLocalIpcSessionWaitForData(hClientSession, 8 /*cMsTimeout*/), VERR_TIMEOUT);
+    uint8_t abBuf[4];
+    size_t cbRead = _4M-1;
+#ifndef RT_OS_WINDOWS
+    RTTESTI_CHECK_RC(RTLocalIpcSessionReadNB(hClientSession, abBuf, sizeof(abBuf), &cbRead), VINF_TRY_AGAIN);
+    RTTESTI_CHECK(cbRead == 0);
+#endif
 
     /* Trigger server disconnect. */
@@ -291,8 +297,11 @@
 
         RTTESTI_CHECK_RC(RTLocalIpcSessionWrite(hClientSession, RT_STR_TUPLE("broken")), VERR_BROKEN_PIPE);
-        uint8_t abBuf[4];
         RTTESTI_CHECK_RC(RTLocalIpcSessionRead(hClientSession, abBuf, sizeof(abBuf), NULL), VERR_BROKEN_PIPE);
-        size_t cbRead = _4M-1;
+        cbRead = _4M-1;
         RTTESTI_CHECK_RC(RTLocalIpcSessionRead(hClientSession, abBuf, sizeof(abBuf), &cbRead), VERR_BROKEN_PIPE);
+#ifndef RT_OS_WINDOWS
+        cbRead = _1G/2;
+        RTTESTI_CHECK_RC(RTLocalIpcSessionReadNB(hClientSession, abBuf, sizeof(abBuf), &cbRead), VERR_BROKEN_PIPE);
+#endif
 
         RTAssertSetMayPanic(fMayPanic);
