From ce0f4b02160ee72d7d2428867fe757bc37c68c98 Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Thu, 25 Mar 2010 11:11:29 -0700 Subject: Fix Win32 socket error handling. This also fixes -http-proxy support on Windows. Change-Id: I741b224511c064412ac39351ed4f1b9146a313a5 --- android/console.c | 4 ++-- migration-tcp-android.c | 4 ++-- net-android.c | 2 +- proxy/proxy_http_rewriter.c | 2 +- qemu-char-android.c | 2 +- slirp-android/tcp_input.c | 3 ++- sockets.c | 20 +++++++++++++------- sockets.h | 5 ++++- telephony/sysdeps_qemu.c | 4 ++-- 9 files changed, 28 insertions(+), 18 deletions(-) diff --git a/android/console.c b/android/console.c index 45da8aa..fa86151 100644 --- a/android/console.c +++ b/android/console.c @@ -231,7 +231,7 @@ static void control_control_write( ControlClient client, const char* buff, in ret = socket_send( client->sock, buff, len); #endif if (ret < 0) { - if (errno != EINTR && errno != EWOULDBLOCK) + if (errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN) return; } else { buff += ret; @@ -496,7 +496,7 @@ control_client_read( void* _client ) #endif if (size < 0) { D(( "size < 0, exiting with %d: %s\n", errno, errno_str )); - if (errno != EWOULDBLOCK && errno != EINTR) + if (errno != EWOULDBLOCK && errno != EAGAIN && errno != EINTR) control_client_destroy( client ); return; } diff --git a/migration-tcp-android.c b/migration-tcp-android.c index 51e1b78..8287e69 100644 --- a/migration-tcp-android.c +++ b/migration-tcp-android.c @@ -107,11 +107,11 @@ MigrationState *tcp_start_outgoing_migration(const char *host_port, if (ret == -1) ret = -(s->get_error(s)); - if (ret == -EINPROGRESS || ret == -EWOULDBLOCK) + if (ret == -EINPROGRESS || ret == -EWOULDBLOCK || ret == -EAGAIN) qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s); } while (ret == -EINTR); - if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) { + if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK && ret != -EAGAIN) { dprintf("connect failed\n"); socket_close(s->fd); qemu_free(s); diff --git a/net-android.c b/net-android.c index da01a61..b7db44a 100644 --- a/net-android.c +++ b/net-android.c @@ -1607,7 +1607,7 @@ static void net_socket_send(void *opaque) size = recv(s->fd, (void *)buf1, sizeof(buf1), 0); if (size < 0) { err = socket_error(); - if (err != EWOULDBLOCK) + if (err != EWOULDBLOCK && err != EAGAIN) goto eoc; } else if (size == 0) { /* end of connection */ diff --git a/proxy/proxy_http_rewriter.c b/proxy/proxy_http_rewriter.c index cb7c94b..afd929c 100644 --- a/proxy/proxy_http_rewriter.c +++ b/proxy/proxy_http_rewriter.c @@ -381,7 +381,7 @@ rewrite_connection_init( RewriteConnection* conn ) conn->state = STATE_CONNECTING; if (socket_connect( root->socket, &service->server_addr ) < 0) { - if (errno == EINPROGRESS || errno == EWOULDBLOCK) { + if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) { PROXY_LOG("%s: connecting", conn->root->name); } else { diff --git a/qemu-char-android.c b/qemu-char-android.c index 05f80e7..671314b 100644 --- a/qemu-char-android.c +++ b/qemu-char-android.c @@ -494,7 +494,7 @@ int send_all(int fd, const void *buf, int len1) ret = send(fd, buf, len, 0); if (ret < 0) { errno = WSAGetLastError(); - if (errno != WSAEWOULDBLOCK) { + if (errno != WSAEWOULDBLOCK && errno != WSAEAGAIN) { return -1; } } else if (ret == 0) { diff --git a/slirp-android/tcp_input.c b/slirp-android/tcp_input.c index 9ecd2eb..c70e3f2 100644 --- a/slirp-android/tcp_input.c +++ b/slirp-android/tcp_input.c @@ -673,7 +673,8 @@ findso: goto cont_input; } - if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) { + if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && + (errno != EWOULDBLOCK) && (errno != EAGAIN)) { u_char code=ICMP_UNREACH_NET; DEBUG_MISC((dfd," tcp fconnect errno = %d-%s\n", errno,errno_str)); diff --git a/sockets.c b/sockets.c index 839b94f..ece2564 100644 --- a/sockets.c +++ b/sockets.c @@ -14,10 +14,12 @@ #include #include #include "qemu_debug.h" +#include "qemu-char.h" #include #include #include "android/utils/path.h" #include "android/utils/debug.h" +#include "android/utils/misc.h" #define D(...) VERBOSE_PRINT(socket,__VA_ARGS__) @@ -74,14 +76,14 @@ static int winsock_error; EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \ EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \ EE(WSAEINTR,EINTR,"interrupted function call") \ - EE(WSAEALREADY,EALREADY,"operation already in progress") \ + EE(WSAEALREADY,EALREADY,"operation already in progress") \ EE(WSAEBADF,EBADF,"bad file descriptor") \ EE(WSAEACCES,EACCES,"permission denied") \ EE(WSAEFAULT,EFAULT,"bad address") \ EE(WSAEINVAL,EINVAL,"invalid argument") \ EE(WSAEMFILE,EMFILE,"too many opened files") \ - EE(WSAEWOULDBLOCK,EAGAIN,"resource temporarily unavailable") \ - EE(WSAEINPROGRESS,EAGAIN,"operation now in progress") \ + EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \ + EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \ EE(WSAEALREADY,EAGAIN,"operation already in progress") \ EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \ EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \ @@ -130,6 +132,8 @@ _fix_errno( void ) const WinsockError* werr = _winsock_errors; int unix = EINVAL; /* generic error code */ + winsock_error = WSAGetLastError(); + for ( ; werr->string != NULL; werr++ ) { if (werr->winsock == winsock_error) { unix = werr->unix; @@ -153,7 +157,7 @@ const char* _errno_str(void) { const WinsockError* werr = _winsock_errors; - const char* result = ""; + const char* result = NULL; for ( ; werr->string; werr++ ) { if (werr->winsock == winsock_error) { @@ -162,9 +166,11 @@ _errno_str(void) } } - if (result == NULL) - result = strerror(errno); - + if (result == NULL) { + result = tempstr_format( + "Unkown socket error (Winsock=0x%08x) errno=%d: %s", + winsock_error, errno, strerror(errno)); + } return result; } #else diff --git a/sockets.h b/sockets.h index 12153e5..2c250cc 100644 --- a/sockets.h +++ b/sockets.h @@ -35,8 +35,11 @@ # ifndef EINTR # define EINTR 10004 # endif +# ifndef EAGAIN +# define EAGAIN 10035 +# endif # ifndef EWOULDBLOCK -# define EWOULDBLOCK 10035 +# define EWOULDBLOCK EAGAIN # endif # ifndef EINPROGRESS # define EINPROGRESS 10036 diff --git a/telephony/sysdeps_qemu.c b/telephony/sysdeps_qemu.c index a88f2fb..48cd81c 100644 --- a/telephony/sysdeps_qemu.c +++ b/telephony/sysdeps_qemu.c @@ -248,7 +248,7 @@ sys_channel_read( SysChannel channel, void* buffer, int size ) if (ret < 0) { if (errno == EINTR) continue; - if (errno == EWOULDBLOCK) + if (errno == EWOULDBLOCK || errno == EAGAIN) break; D( "%s: after reading %d bytes, recv() returned error %d: %s\n", __FUNCTION__, size - len, errno, errno_str); @@ -275,7 +275,7 @@ sys_channel_write( SysChannel channel, const void* buffer, int size ) if (ret < 0) { if (errno == EINTR) continue; - if (errno == EWOULDBLOCK) + if (errno == EWOULDBLOCK || errno == EAGAIN) break; D( "%s: send() returned error %d: %s\n", __FUNCTION__, errno, errno_str); -- cgit v1.1