Slightly cheesy size-tip implementation. This is suboptimal in two ways:
[u/mdw/putty] / unix / uxnet.c
index ad25ef5..e4e07b0 100644 (file)
@@ -106,77 +106,7 @@ void sk_cleanup(void)
 
 char *error_string(int error)
 {
-    switch (error) {
-      case EACCES:
-       return "Network error: Permission denied";
-      case EADDRINUSE:
-       return "Network error: Address already in use";
-      case EADDRNOTAVAIL:
-       return "Network error: Cannot assign requested address";
-      case EAFNOSUPPORT:
-       return
-           "Network error: Address family not supported by protocol family";
-      case EALREADY:
-       return "Network error: Operation already in progress";
-      case ECONNABORTED:
-       return "Network error: Software caused connection abort";
-      case ECONNREFUSED:
-       return "Network error: Connection refused";
-      case ECONNRESET:
-       return "Network error: Connection reset by peer";
-      case EDESTADDRREQ:
-       return "Network error: Destination address required";
-      case EFAULT:
-       return "Network error: Bad address";
-      case EHOSTDOWN:
-       return "Network error: Host is down";
-      case EHOSTUNREACH:
-       return "Network error: No route to host";
-      case EINPROGRESS:
-       return "Network error: Operation now in progress";
-      case EINTR:
-       return "Network error: Interrupted function call";
-      case EINVAL:
-       return "Network error: Invalid argument";
-      case EISCONN:
-       return "Network error: Socket is already connected";
-      case EMFILE:
-       return "Network error: Too many open files";
-      case EMSGSIZE:
-       return "Network error: Message too long";
-      case ENETDOWN:
-       return "Network error: Network is down";
-      case ENETRESET:
-       return "Network error: Network dropped connection on reset";
-      case ENETUNREACH:
-       return "Network error: Network is unreachable";
-      case ENOBUFS:
-       return "Network error: No buffer space available";
-      case ENOPROTOOPT:
-       return "Network error: Bad protocol option";
-      case ENOTCONN:
-       return "Network error: Socket is not connected";
-      case ENOTSOCK:
-       return "Network error: Socket operation on non-socket";
-      case EOPNOTSUPP:
-       return "Network error: Operation not supported";
-      case EPFNOSUPPORT:
-       return "Network error: Protocol family not supported";
-      case EPROTONOSUPPORT:
-       return "Network error: Protocol not supported";
-      case EPROTOTYPE:
-       return "Network error: Protocol wrong type for socket";
-      case ESHUTDOWN:
-       return "Network error: Cannot send after socket shutdown";
-      case ESOCKTNOSUPPORT:
-       return "Network error: Socket type not supported";
-      case ETIMEDOUT:
-       return "Network error: Connection timed out";
-      case EWOULDBLOCK:
-       return "Network error: Resource temporarily unavailable";
-      default:
-       return "Unknown network error";
-    }
+    return strerror(error);
 }
 
 SockAddr sk_namelookup(char *host, char **canonicalname)
@@ -208,13 +138,15 @@ SockAddr sk_namelookup(char *host, char **canonicalname)
                if ( (h = gethostbyname(host)) )
                    ret->family = AF_INET;
            }
-           if (ret->family == 0)
+           if (ret->family == 0) {
                ret->error = (h_errno == HOST_NOT_FOUND ||
                              h_errno == NO_DATA ||
                              h_errno == NO_ADDRESS ? "Host does not exist" :
                              h_errno == TRY_AGAIN ?
                              "Temporary name service failure" :
                              "gethostbyname: unknown error");
+               return ret;
+           }
        }
 
 #ifdef IPV6
@@ -808,10 +740,12 @@ int select_result(int fd, int event)
 
        /*
         * If we reach here, this is an oobinline socket, which
-        * means we should set s->oobpending and then fall through
-        * to the read case.
+        * means we should set s->oobpending and then deal with it
+        * when we get called for the readability event (which
+        * should also occur).
         */
        s->oobpending = TRUE;
+        break;
       case 1:                         /* readable; also acceptance */
        if (s->listener) {
            /*
@@ -862,7 +796,7 @@ int select_result(int fd, int event)
        } else
            atmark = 1;
 
-       ret = recv(s->s, buf, sizeof(buf), 0);
+       ret = recv(s->s, buf, s->oobpending ? 1 : sizeof(buf), 0);
        noise_ultralight(ret);
        if (ret < 0) {
            if (errno == EWOULDBLOCK) {