Robert Shearman : wininet: Correctly set the last error when a called Unix network

Alexandre Julliard julliard at wine.codeweavers.com
Sat Dec 3 12:31:15 CST 2005


Module: wine
Branch: refs/heads/master
Commit: efd067f2c36b118add41e2566a6957a5cdc5c5df
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=efd067f2c36b118add41e2566a6957a5cdc5c5df

Author: Robert Shearman <rob at codeweavers.com>
Date:   Sat Dec  3 18:10:14 2005 +0100

wininet: Correctly set the last error when a called Unix network
function fails.

---

 dlls/wininet/http.c          |    5 --
 dlls/wininet/internet.c      |    2 +
 dlls/wininet/netconnection.c |   86 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 87 insertions(+), 6 deletions(-)

diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c
index 23affbc..f234530 100644
--- a/dlls/wininet/http.c
+++ b/dlls/wininet/http.c
@@ -38,8 +38,6 @@
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif
-#include <errno.h>
-#include <string.h>
 #include <time.h>
 #include <assert.h>
 
@@ -2237,10 +2235,7 @@ static BOOL HTTP_OpenConnection(LPWININE
 
     if (!NETCON_connect(&lpwhr->netConnection, (struct sockaddr *)&lpwhs->socketAddress,
                       sizeof(lpwhs->socketAddress)))
-    {
-       WARN("Unable to connect to host (%s)\n", strerror(errno));
        goto lend;
-    }
 
     if (lpwhr->hdr.dwFlags & INTERNET_FLAG_SECURE)
     {
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c
index d3e84bb..b91c9ff 100644
--- a/dlls/wininet/internet.c
+++ b/dlls/wininet/internet.c
@@ -2965,6 +2965,8 @@ void INTERNET_SetLastError(DWORD dwError
 DWORD INTERNET_GetLastError(void)
 {
     LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex);
+    /* TlsGetValue clears last error, so set it again here */
+    SetLastError(lpwite->dwError);
     return lpwite->dwError;
 }
 
diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c
index 05c6562..3c13818 100644
--- a/dlls/wininet/netconnection.c
+++ b/dlls/wininet/netconnection.c
@@ -43,6 +43,11 @@
 #include "wininet.h"
 #include "winerror.h"
 
+/* To avoid conflicts with the Unix socket headers. we only need it for
+ * the error codes anyway. */
+#define USE_WS_PREFIX
+#include "winsock2.h"
+
 #include "wine/debug.h"
 #include "internet.h"
 
@@ -192,6 +197,70 @@ BOOL NETCON_connected(WININET_NETCONNECT
         return TRUE;
 }
 
+/* translate a unix error code into a winsock one */
+static int sock_get_error( int err )
+{
+    switch (err)
+    {
+        case EINTR:             return WSAEINTR;
+        case EBADF:             return WSAEBADF;
+        case EPERM:
+        case EACCES:            return WSAEACCES;
+        case EFAULT:            return WSAEFAULT;
+        case EINVAL:            return WSAEINVAL;
+        case EMFILE:            return WSAEMFILE;
+        case EWOULDBLOCK:       return WSAEWOULDBLOCK;
+        case EINPROGRESS:       return WSAEINPROGRESS;
+        case EALREADY:          return WSAEALREADY;
+        case ENOTSOCK:          return WSAENOTSOCK;
+        case EDESTADDRREQ:      return WSAEDESTADDRREQ;
+        case EMSGSIZE:          return WSAEMSGSIZE;
+        case EPROTOTYPE:        return WSAEPROTOTYPE;
+        case ENOPROTOOPT:       return WSAENOPROTOOPT;
+        case EPROTONOSUPPORT:   return WSAEPROTONOSUPPORT;
+        case ESOCKTNOSUPPORT:   return WSAESOCKTNOSUPPORT;
+        case EOPNOTSUPP:        return WSAEOPNOTSUPP;
+        case EPFNOSUPPORT:      return WSAEPFNOSUPPORT;
+        case EAFNOSUPPORT:      return WSAEAFNOSUPPORT;
+        case EADDRINUSE:        return WSAEADDRINUSE;
+        case EADDRNOTAVAIL:     return WSAEADDRNOTAVAIL;
+        case ENETDOWN:          return WSAENETDOWN;
+        case ENETUNREACH:       return WSAENETUNREACH;
+        case ENETRESET:         return WSAENETRESET;
+        case ECONNABORTED:      return WSAECONNABORTED;
+        case EPIPE:
+        case ECONNRESET:        return WSAECONNRESET;
+        case ENOBUFS:           return WSAENOBUFS;
+        case EISCONN:           return WSAEISCONN;
+        case ENOTCONN:          return WSAENOTCONN;
+        case ESHUTDOWN:         return WSAESHUTDOWN;
+        case ETOOMANYREFS:      return WSAETOOMANYREFS;
+        case ETIMEDOUT:         return WSAETIMEDOUT;
+        case ECONNREFUSED:      return WSAECONNREFUSED;
+        case ELOOP:             return WSAELOOP;
+        case ENAMETOOLONG:      return WSAENAMETOOLONG;
+        case EHOSTDOWN:         return WSAEHOSTDOWN;
+        case EHOSTUNREACH:      return WSAEHOSTUNREACH;
+        case ENOTEMPTY:         return WSAENOTEMPTY;
+#ifdef EPROCLIM
+        case EPROCLIM:          return WSAEPROCLIM;
+#endif
+#ifdef EUSERS
+        case EUSERS:            return WSAEUSERS;
+#endif
+#ifdef EDQUOT
+        case EDQUOT:            return WSAEDQUOT;
+#endif
+#ifdef ESTALE
+        case ESTALE:            return WSAESTALE;
+#endif
+#ifdef EREMOTE
+        case EREMOTE:           return WSAEREMOTE;
+#endif
+    default: errno=err; perror("sock_set_error"); return WSAEFAULT;
+    }
+}
+
 /******************************************************************************
  * NETCON_create
  * Basically calls 'socket()'
@@ -206,7 +275,10 @@ BOOL NETCON_create(WININET_NETCONNECTION
 
     connection->socketFD = socket(domain, type, protocol);
     if (connection->socketFD == -1)
+    {
+        INTERNET_SetLastError(sock_get_error(errno));
         return FALSE;
+    }
     return TRUE;
 }
 
@@ -239,7 +311,10 @@ BOOL NETCON_close(WININET_NETCONNECTION 
     connection->socketFD = -1;
 
     if (result == -1)
+    {
+        INTERNET_SetLastError(sock_get_error(errno));
         return FALSE;
+    }
     return TRUE;
 }
 
@@ -358,6 +433,9 @@ BOOL NETCON_connect(WININET_NETCONNECTIO
     result = connect(connection->socketFD, serv_addr, addrlen);
     if (result == -1)
     {
+        WARN("Unable to connect to host (%s)\n", strerror(errno));
+        INTERNET_SetLastError(sock_get_error(errno));
+
         closesocket(connection->socketFD);
         connection->socketFD = -1;
         return FALSE;
@@ -379,7 +457,10 @@ BOOL NETCON_send(WININET_NETCONNECTION *
     {
 	*sent = send(connection->socketFD, msg, len, flags);
 	if (*sent == -1)
+	{
+	    INTERNET_SetLastError(sock_get_error(errno));
 	    return FALSE;
+	}
         return TRUE;
     }
     else
@@ -410,7 +491,10 @@ BOOL NETCON_recv(WININET_NETCONNECTION *
     {
 	*recvd = recv(connection->socketFD, buf, len, flags);
 	if (*recvd == -1)
+	{
+	    INTERNET_SetLastError(sock_get_error(errno));
 	    return FALSE;
+	}
         return TRUE;
     }
     else
@@ -498,7 +582,7 @@ BOOL NETCON_getNextLine(WININET_NETCONNE
 	    {
 		if (recv(connection->socketFD, &lpszBuffer[nRecv], 1, 0) <= 0)
 		{
-		    INTERNET_SetLastError(ERROR_CONNECTION_ABORTED); /* fixme: right error? */
+		    INTERNET_SetLastError(sock_get_error(errno));
 		    goto lend;
 		}
 




More information about the wine-cvs mailing list