Index: /trunk/include/iprt/message.h
===================================================================
--- /trunk/include/iprt/message.h	(revision 26682)
+++ /trunk/include/iprt/message.h	(revision 26683)
@@ -71,4 +71,26 @@
 
 /**
+ * Same as RTMsgError() except for the return value.
+ *
+ * @returns @a enmExitCode
+ * @param   enmExitCode     What to exit code to return.  This is mainly for
+ *                          saving some vertical space in the source file.
+ * @param   pszFormat       The message format string.
+ * @param   ...             Format arguments.
+ */
+RTDECL(RTEXITCODE) RTMsgErrorExit(RTEXITCODE enmExitcode, const char *pszFormat, ...);
+
+/**
+ * Same as RTMsgErrorV() except for the return value.
+ *
+ * @returns @a enmExitCode
+ * @param   enmExitCode     What to exit code to return.  This is mainly for
+ *                          saving some vertical space in the source file.
+ * @param   pszFormat       The message format string.
+ * @param   va              Format arguments.
+ */
+RTDECL(RTEXITCODE) RTMsgErrorExitV(RTEXITCODE enmExitCode, const char *pszFormat, va_list va);
+
+/**
  * Print an error message for a RTR3Init failure and suggest an exit code.
  *
@@ -84,5 +106,5 @@
  * @param   rcRTR3Init      The status code returned by RTR3Init.
  */
-RTDECL(int)  RTMsgInitFailure(int rcRTR3Init);
+RTDECL(RTEXITCODE) RTMsgInitFailure(int rcRTR3Init);
 
 /** @} */
Index: /trunk/include/iprt/tcp.h
===================================================================
--- /trunk/include/iprt/tcp.h	(revision 26682)
+++ /trunk/include/iprt/tcp.h	(revision 26683)
@@ -126,4 +126,26 @@
 
 /**
+ * Listen and accept one incomming connection.
+ *
+ * This is an alternative to RTTcpServerListen for the use the callbacks are not
+ * possible.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_TCP_SERVER_SHUTDOWN if shut down by RTTcpServerShutdown.
+ * @retval  VERR_INTERRUPTED if the listening was interrupted.
+ *
+ * @param   pServer         The server handle as returned from RTTcpServerCreateEx().
+ * @param   pSockClient     Where to return the socket handle to the client
+ *                          connection (on success only).  Use
+ *                          RTTcpServerDisconnectClient() to clean it, this must
+ *                          be done before the next call to RTTcpServerListen2.
+ *
+ * @todo    This can easily be extended to support multiple connections by
+ *          adding a new state and a RTTcpServerDisconnectClient variant for
+ *          closing client sockets.
+ */
+RTR3DECL(int) RTTcpServerListen2(PRTTCPSERVER pServer, PRTSOCKET pSockClient);
+
+/**
  * Terminate the open connection to the server.
  *
@@ -176,4 +198,6 @@
  *
  * @returns iprt status code.
+ * @retval  VERR_INTERRUPTED if interrupted before anything was written.
+ *
  * @param   Sock        Socket descriptor.
  * @param   pvBuffer    Buffer to write data to socket.
Index: /trunk/include/iprt/test.h
===================================================================
--- /trunk/include/iprt/test.h	(revision 26682)
+++ /trunk/include/iprt/test.h	(revision 26683)
@@ -98,11 +98,11 @@
    @endcode
  *
- * @returns 0 on success. On failure an error message is printed and
- *          a suitable exit code is return.
+ * @returns RTEXITCODE_SUCCESS on success.  On failure an error message is
+ *          printed and a suitable exit code is return.
  *
  * @param   pszTest     The test name.
  * @param   phTest      Where to store the test instance handle.
  */
-RTR3DECL(int) RTTestInitAndCreate(const char *pszTest, PRTTEST phTest);
+RTR3DECL(RTEXITCODE) RTTestInitAndCreate(const char *pszTest, PRTTEST phTest);
 
 /**
@@ -233,5 +233,5 @@
  *                      associated with the calling thread.
  */
-RTR3DECL(int) RTTestSummaryAndDestroy(RTTEST hTest);
+RTR3DECL(RTEXITCODE) RTTestSummaryAndDestroy(RTTEST hTest);
 
 /**
@@ -244,5 +244,5 @@
  * @param   va              Arguments for the reason format string.
  */
-RTR3DECL(int) RTTestSkipAndDestroyV(RTTEST hTest, const char *pszReasonFmt, va_list va);
+RTR3DECL(RTEXITCODE) RTTestSkipAndDestroyV(RTTEST hTest, const char *pszReasonFmt, va_list va);
 
 /**
@@ -255,5 +255,5 @@
  * @param   ...             Arguments for the reason format string.
  */
-RTR3DECL(int) RTTestSkipAndDestroy(RTTEST hTest, const char *pszReasonFmt, ...);
+RTR3DECL(RTEXITCODE) RTTestSkipAndDestroy(RTTEST hTest, const char *pszReasonFmt, ...);
 
 /**
Index: /trunk/include/iprt/types.h
===================================================================
--- /trunk/include/iprt/types.h	(revision 26682)
+++ /trunk/include/iprt/types.h	(revision 26683)
@@ -1512,4 +1512,27 @@
 
 
+/**
+ * Process exit codes.
+ */
+typedef enum RTEXITCODE
+{
+    /** Success. */
+    RTEXITCODE_SUCCESS = 0,
+    /** General failure. */
+    RTEXITCODE_FAILURE = 1,
+    /** Invalid arguments.  */
+    RTEXITCODE_SYNTAX = 2,
+    /** Initialization failure (usually IPRT, but could be used for other
+     *  components as well). */
+    RTEXITCODE_INIT = 3,
+    /** Test skipped. */
+    RTEXITCODE_SKIPPED = 4,
+    /** The end of valid exit codes. */
+    RTEXITCODE_END,
+    /** The usual 32-bit type hack. */
+    RTEXITCODE_32BIT_HACK = 0x7fffffff
+} RTEXITCODE;
+
+
 #ifdef __cplusplus
 /**
Index: /trunk/src/VBox/Runtime/common/misc/message.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/misc/message.cpp	(revision 26682)
+++ /trunk/src/VBox/Runtime/common/misc/message.cpp	(revision 26683)
@@ -99,5 +99,24 @@
 
 
-RTDECL(int) RTMsgInitFailure(int rcRTR3Init)
+RTDECL(RTEXITCODE) RTMsgErrorExit(RTEXITCODE enmExitCode, const char *pszFormat, ...)
+{
+    va_list va;
+    va_start(va, pszFormat);
+    RTMsgErrorV(pszFormat, va);
+    va_end(va);
+    return enmExitCode;
+}
+RT_EXPORT_SYMBOL(RTMsgErrorExitV);
+
+
+RTDECL(RTEXITCODE) RTMsgErrorExitV(RTEXITCODE enmExitCode, const char *pszFormat, va_list va)
+{
+    RTMsgErrorV(pszFormat, va);
+    return enmExitCode;
+}
+RT_EXPORT_SYMBOL(RTMsgErrorExitV);
+
+
+RTDECL(RTEXITCODE) RTMsgInitFailure(int rcRTR3Init)
 {
     if (   g_offrtProcName
@@ -108,5 +127,5 @@
     else
         RTStrmPrintf(g_pStdErr, "fatal error: RTR3Init: %Rrc\n", rcRTR3Init);
-    return 12;
+    return RTEXITCODE_INIT;
 }
 RT_EXPORT_SYMBOL(RTMsgInitFailure);
Index: /trunk/src/VBox/Runtime/r3/tcp.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/tcp.cpp	(revision 26682)
+++ /trunk/src/VBox/Runtime/r3/tcp.cpp	(revision 26683)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2007 Sun Microsystems, Inc.
+ * Copyright (C) 2006-2010 Sun Microsystems, Inc.
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -35,5 +35,4 @@
 #ifdef RT_OS_WINDOWS
 # include <winsock.h>
-# include <limits.h>
 #else /* !RT_OS_WINDOWS */
 # include <errno.h>
@@ -50,4 +49,5 @@
 # include <unistd.h>
 #endif /* !RT_OS_WINDOWS */
+#include <limits.h>
 
 #include "internal/iprt.h"
@@ -657,4 +657,95 @@
 
 /**
+ * Listen and accept one incomming connection.
+ *
+ * This is an alternative to RTTcpServerListen for the use the callbacks are not
+ * possible.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_TCP_SERVER_SHUTDOWN if shut down by RTTcpServerShutdown.
+ * @retval  VERR_INTERRUPTED if the listening was interrupted.
+ *
+ * @param   pServer         The server handle as returned from RTTcpServerCreateEx().
+ * @param   pSockClient     Where to return the socket handle to the client
+ *                          connection (on success only).  Use
+ *                          RTTcpServerDisconnectClient() to clean it, this must
+ *                          be done before the next call to RTTcpServerListen2.
+ *
+ * @todo    This can easily be extended to support multiple connections by
+ *          adding a new state and a RTTcpServerDisconnectClient variant for
+ *          closing client sockets.
+ */
+RTR3DECL(int) RTTcpServerListen2(PRTTCPSERVER pServer, PRTSOCKET pSockClient)
+{
+    /*
+     * Validate input and retain the instance.
+     */
+    AssertPtrReturn(pSockClient, VERR_INVALID_HANDLE);
+    *pSockClient = NIL_RTSOCKET;
+    AssertReturn(pServer->u32Magic == RTTCPSERVER_MAGIC, VERR_INVALID_HANDLE);
+    AssertReturn(RTMemPoolRetain(pServer) != UINT32_MAX, VERR_INVALID_HANDLE);
+
+    int rc = VERR_INVALID_STATE;
+    for (;;)
+    {
+        /*
+         * Change state to accepting.
+         */
+        RTTCPSERVERSTATE    enmState   = pServer->enmState;
+        RTSOCKET            SockServer = pServer->SockServer;
+        if (    enmState != RTTCPSERVERSTATE_SERVING
+            &&  enmState != RTTCPSERVERSTATE_CREATED)
+        {
+            rc = rcTcpServerListenCleanup(pServer);
+            break;
+        }
+        if (!rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_ACCEPTING, enmState))
+            continue;
+        Assert(!pServer->pfnServe);
+        Assert(!pServer->pvUser);
+        Assert(pServer->Thread == NIL_RTTHREAD);
+        Assert(pServer->SockClient == NIL_RTSOCKET);
+
+        /*
+         * Accept connection.
+         */
+        struct sockaddr_in  RemoteAddr;
+        socklen_t           cbRemoteAddr = sizeof(RemoteAddr);
+        RTSOCKET            Socket;
+        RT_ZERO(RemoteAddr);
+        rtTcpErrorReset();
+        Socket = accept(SockServer, (struct sockaddr *)&RemoteAddr, &cbRemoteAddr);
+        if (Socket == -1)
+        {
+            rc = rtTcpError();
+            if (!rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_CREATED, RTTCPSERVERSTATE_ACCEPTING))
+                rc = rcTcpServerListenCleanup(pServer);
+            if (RT_FAILURE(rc))
+                break;
+            continue;
+        }
+
+        /*
+         * Chance to the 'serving' state and return the socket.
+         */
+        if (rtTcpServerTrySetState(pServer, RTTCPSERVERSTATE_SERVING, RTTCPSERVERSTATE_ACCEPTING))
+        {
+            *pSockClient = Socket;
+            rc = VINF_SUCCESS;
+        }
+        else
+        {
+            rtTcpClose(Socket, "RTTcpServerListen2", true /*fTryGracefulShutdown*/);
+            rc = rcTcpServerListenCleanup(pServer);
+        }
+        break;
+    }
+
+    RTMemPoolRelease(RTMEMPOOL_DEFAULT, pServer);
+    return rc;
+}
+
+
+/**
  * Terminate the open connection to the server.
  *
@@ -855,22 +946,50 @@
 RTR3DECL(int)  RTTcpWrite(RTSOCKET Sock, const void *pvBuffer, size_t cbBuffer)
 {
-
-    do
-    {
+    /*
+     * Try write all at once.
+     */
 #ifdef RT_OS_WINDOWS
-        int    cbNow = cbBuffer >= INT_MAX/2 ? INT_MAX/2 : (int)cbBuffer;
+    int     cbNow     = cbBuffer >= INT_MAX / 2 ? INT_MAX / 2 : (int)cbBuffer;
 #else
-        size_t cbNow = cbBuffer;
-#endif
-        ssize_t cbWritten = send(Sock, (const char *)pvBuffer, cbNow, MSG_NOSIGNAL);
-        if (cbWritten < 0)
-            return rtTcpError();
-        AssertMsg(cbBuffer >= (size_t)cbWritten, ("Wrote more than we requested!!! cbWritten=%d cbBuffer=%d rtTcpError()=%d\n",
-                                                  cbWritten, cbBuffer, rtTcpError()));
-        cbBuffer -= cbWritten;
-        pvBuffer = (char *)pvBuffer + cbWritten;
-    } while (cbBuffer);
-
-    return VINF_SUCCESS;
+    size_t  cbNow     = cbBuffer >= SSIZE_MAX   ? SSIZE_MAX   :      cbBuffer;
+#endif
+    ssize_t cbWritten = send(Sock, (const char *)pvBuffer, cbNow, MSG_NOSIGNAL);
+    if (RT_LIKELY((size_t)cbWritten == cbBuffer && cbWritten >= 0))
+        return VINF_SUCCESS;
+    if (cbWritten < 0)
+        return rtTcpError();
+
+    /*
+     * Unfinished business, write the remainder of the request.  Must ignore
+     * VERR_INTERRUPTED here if we've managed to send something.
+     */
+    size_t cbSentSoFar = 0;
+    for (;;)
+    {
+        /* advance */
+        cbBuffer    -= (size_t)cbWritten;
+        if (!cbBuffer)
+            return VINF_SUCCESS;
+        cbSentSoFar += (size_t)cbWritten;
+        pvBuffer     = (char const *)pvBuffer + cbWritten;
+
+        /* send */
+#ifdef RT_OS_WINDOWS
+        cbNow = cbBuffer >= INT_MAX / 2 ? INT_MAX / 2 : (int)cbBuffer;
+#else
+        cbNow = cbBuffer >= SSIZE_MAX   ? SSIZE_MAX   :      cbBuffer;
+#endif
+        cbWritten = send(Sock, (const char *)pvBuffer, cbNow, MSG_NOSIGNAL);
+        if (cbWritten >= 0)
+            AssertMsg(cbBuffer >= (size_t)cbWritten, ("Wrote more than we requested!!! cbWritten=%zu cbBuffer=%zu rtTcpError()=%d\n",
+                                                      cbWritten, cbBuffer, rtTcpError()));
+        else
+        {
+            int rc = rtTcpError();
+            if (rc != VERR_INTERNAL_ERROR || cbSentSoFar == 0)
+                return rc;
+            cbWritten = 0;
+        }
+    }
 }
 
Index: /trunk/src/VBox/Runtime/r3/test.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/test.cpp	(revision 26682)
+++ /trunk/src/VBox/Runtime/r3/test.cpp	(revision 26683)
@@ -289,5 +289,5 @@
 
 
-RTR3DECL(int) RTTestInitAndCreate(const char *pszTest, PRTTEST phTest)
+RTR3DECL(RTEXITCODE) RTTestInitAndCreate(const char *pszTest, PRTTEST phTest)
 {
     int rc = RTR3Init();
@@ -295,5 +295,5 @@
     {
         RTStrmPrintf(g_pStdErr, "%s: fatal error: RTR3Init failed with rc=%Rrc\n",  pszTest, rc);
-        return 16;
+        return RTEXITCODE_INIT;
     }
     rc = RTTestCreate(pszTest, phTest);
@@ -301,7 +301,7 @@
     {
         RTStrmPrintf(g_pStdErr, "%s: fatal error: RTTestCreate failed with rc=%Rrc\n",  pszTest, rc);
-        return 17;
-    }
-    return 0;
+        return RTEXITCODE_INIT;
+    }
+    return RTEXITCODE_SUCCESS;
 }
 
@@ -806,8 +806,8 @@
  *                      associated with the calling thread.
  */
-RTR3DECL(int) RTTestSummaryAndDestroy(RTTEST hTest)
+RTR3DECL(RTEXITCODE) RTTestSummaryAndDestroy(RTTEST hTest)
 {
     PRTTESTINT pTest = hTest;
-    RTTEST_GET_VALID_RETURN_RC(pTest, 2);
+    RTTEST_GET_VALID_RETURN_RC(pTest, RTEXITCODE_FAILURE);
 
     RTCritSectEnter(&pTest->Lock);
@@ -815,25 +815,25 @@
     RTCritSectLeave(&pTest->Lock);
 
-    int rc;
+    RTEXITCODE enmExitCode;
     if (!pTest->cErrors)
     {
         RTTestPrintfNl(hTest, RTTESTLVL_ALWAYS, "SUCCESS\n", pTest->cErrors);
-        rc = 0;
+        enmExitCode = RTEXITCODE_SUCCESS;
     }
     else
     {
         RTTestPrintfNl(hTest, RTTESTLVL_ALWAYS, "FAILURE - %u errors\n", pTest->cErrors);
-        rc = 1;
+        enmExitCode = RTEXITCODE_FAILURE;
     }
 
     RTTestDestroy(pTest);
-    return rc;
-}
-
-
-RTR3DECL(int) RTTestSkipAndDestroyV(RTTEST hTest, const char *pszReasonFmt, va_list va)
+    return enmExitCode;
+}
+
+
+RTR3DECL(RTEXITCODE) RTTestSkipAndDestroyV(RTTEST hTest, const char *pszReasonFmt, va_list va)
 {
     PRTTESTINT pTest = hTest;
-    RTTEST_GET_VALID_RETURN_RC(pTest, 2);
+    RTTEST_GET_VALID_RETURN_RC(pTest, RTEXITCODE_SKIPPED);
 
     RTCritSectEnter(&pTest->Lock);
@@ -841,5 +841,5 @@
     RTCritSectLeave(&pTest->Lock);
 
-    int rc;
+    RTEXITCODE enmExitCode;
     if (!pTest->cErrors)
     {
@@ -847,24 +847,24 @@
             RTTestPrintfNlV(hTest, RTTESTLVL_FAILURE, pszReasonFmt, va);
         RTTestPrintfNl(hTest, RTTESTLVL_ALWAYS, "SKIPPED\n", pTest->cErrors);
-        rc = 2;
+        enmExitCode = RTEXITCODE_SKIPPED;
     }
     else
     {
         RTTestPrintfNl(hTest, RTTESTLVL_ALWAYS, "FAILURE - %u errors\n", pTest->cErrors);
-        rc = 1;
+        enmExitCode = RTEXITCODE_FAILURE;
     }
 
     RTTestDestroy(pTest);
-    return rc;
-}
-
-
-RTR3DECL(int) RTTestSkipAndDestroy(RTTEST hTest, const char *pszReasonFmt, ...)
+    return enmExitCode;
+}
+
+
+RTR3DECL(RTEXITCODE) RTTestSkipAndDestroy(RTTEST hTest, const char *pszReasonFmt, ...)
 {
     va_list va;
     va_start(va, pszReasonFmt);
-    int rc = RTTestSkipAndDestroyV(hTest, pszReasonFmt, va);
+    RTEXITCODE enmExitCode = RTTestSkipAndDestroyV(hTest, pszReasonFmt, va);
     va_end(va);
-    return rc;
+    return enmExitCode;
 }
 
