]> Savannah Git Hosting - gnulib.git/commitdiff
Ensure EBADF returns for socket functions on mingw.
authorBruno Haible <bruno@clisp.org>
Tue, 20 Sep 2011 22:20:59 +0000 (00:20 +0200)
committerBruno Haible <bruno@clisp.org>
Tue, 20 Sep 2011 22:20:59 +0000 (00:20 +0200)
* lib/accept.c (rpl_accept): Fail with error EBADF if the file
descriptor is invalid.
* lib/bind.c (rpl_bind): Likewise.
* lib/connect.c (rpl_connect): Likewise.
* lib/getpeername.c (rpl_getpeername): Likewise.
* lib/getsockname.c (rpl_getsockname): Likewise.
* lib/getsockopt.c (rpl_getsockopt): Likewise.
* lib/listen.c (rpl_listen): Likewise.
* lib/recv.c (rpl_recv): Likewise.
* lib/recvfrom.c (rpl_recvfrom): Likewise.
* lib/send.c (rpl_send): Likewise.
* lib/sendto.c (rpl_sendto): Likewise.
* lib/setsockopt.c (rpl_setsockopt): Likewise.
* lib/shutdown.c (rpl_shutdown): Likewise.

14 files changed:
ChangeLog
lib/accept.c
lib/bind.c
lib/connect.c
lib/getpeername.c
lib/getsockname.c
lib/getsockopt.c
lib/listen.c
lib/recv.c
lib/recvfrom.c
lib/send.c
lib/sendto.c
lib/setsockopt.c
lib/shutdown.c

index a653b15bac93f3e36ddb98d6043bc52a3db17042..542c6fad4b7016cd0127f1442432444c31b94966 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2011-09-20  Bruno Haible  <bruno@clisp.org>
+
+       Ensure EBADF returns for socket functions on mingw.
+       * lib/accept.c (rpl_accept): Fail with error EBADF if the file
+       descriptor is invalid.
+       * lib/bind.c (rpl_bind): Likewise.
+       * lib/connect.c (rpl_connect): Likewise.
+       * lib/getpeername.c (rpl_getpeername): Likewise.
+       * lib/getsockname.c (rpl_getsockname): Likewise.
+       * lib/getsockopt.c (rpl_getsockopt): Likewise.
+       * lib/listen.c (rpl_listen): Likewise.
+       * lib/recv.c (rpl_recv): Likewise.
+       * lib/recvfrom.c (rpl_recvfrom): Likewise.
+       * lib/send.c (rpl_send): Likewise.
+       * lib/sendto.c (rpl_sendto): Likewise.
+       * lib/setsockopt.c (rpl_setsockopt): Likewise.
+       * lib/shutdown.c (rpl_shutdown): Likewise.
+
 2011-09-20  Bruno Haible  <bruno@clisp.org>
 
        select tests: EBADF tests.
index 5591fa50a41560d32f46a6e8da0af02d08ef5a27..01faf54209480c400b741ca3c64310724c41fc74 100644 (file)
 int
 rpl_accept (int fd, struct sockaddr *addr, socklen_t *addrlen)
 {
-  SOCKET fh = accept (FD_TO_SOCKET (fd), addr, addrlen);
-  if (fh == INVALID_SOCKET)
+  SOCKET sock = FD_TO_SOCKET (fd);
+
+  if (sock == INVALID_SOCKET)
     {
-      set_winsock_errno ();
+      errno = EBADF;
       return -1;
     }
   else
-    return SOCKET_TO_FD (fh);
+    {
+      SOCKET fh = accept (sock, addr, addrlen);
+      if (fh == INVALID_SOCKET)
+        {
+          set_winsock_errno ();
+          return -1;
+        }
+      else
+        return SOCKET_TO_FD (fh);
+    }
 }
index e6d959dce56a718ce9166ddcff94cf3bf5edbc94..baaea59b6062496db7ec269786483f11cb35e362 100644 (file)
@@ -32,9 +32,18 @@ int
 rpl_bind (int fd, const struct sockaddr *sockaddr, socklen_t len)
 {
   SOCKET sock = FD_TO_SOCKET (fd);
-  int r = bind (sock, sockaddr, len);
-  if (r < 0)
-    set_winsock_errno ();
 
-  return r;
+  if (sock == INVALID_SOCKET)
+    {
+      errno = EBADF;
+      return -1;
+    }
+  else
+    {
+      int r = bind (sock, sockaddr, len);
+      if (r < 0)
+        set_winsock_errno ();
+
+      return r;
+    }
 }
index ea03e77bc04ef5951ad3ad92074647e5db669b32..afd13b9f8d08ee0dfe39ef44061aa4dd766b452c 100644 (file)
@@ -32,16 +32,25 @@ int
 rpl_connect (int fd, const struct sockaddr *sockaddr, socklen_t len)
 {
   SOCKET sock = FD_TO_SOCKET (fd);
-  int r = connect (sock, sockaddr, len);
-  if (r < 0)
-    {
-      /* EINPROGRESS is not returned by WinSock 2.0; for backwards
-         compatibility, connect(2) uses EWOULDBLOCK.  */
-      if (WSAGetLastError () == WSAEWOULDBLOCK)
-        WSASetLastError (WSAEINPROGRESS);
 
-      set_winsock_errno ();
+  if (sock == INVALID_SOCKET)
+    {
+      errno = EBADF;
+      return -1;
+    }
+  else
+    {
+      int r = connect (sock, sockaddr, len);
+      if (r < 0)
+        {
+          /* EINPROGRESS is not returned by WinSock 2.0; for backwards
+             compatibility, connect(2) uses EWOULDBLOCK.  */
+          if (WSAGetLastError () == WSAEWOULDBLOCK)
+            WSASetLastError (WSAEINPROGRESS);
+
+          set_winsock_errno ();
+        }
+
+      return r;
     }
-
-  return r;
 }
index 9e540a1fd36b0bc4c53c1e5771b457ad4a63c8d0..abe5a40b6741b648a99e7c01afc34dbddba05323 100644 (file)
@@ -32,9 +32,18 @@ int
 rpl_getpeername (int fd, struct sockaddr *addr, socklen_t *addrlen)
 {
   SOCKET sock = FD_TO_SOCKET (fd);
-  int r = getpeername (sock, addr, addrlen);
-  if (r < 0)
-    set_winsock_errno ();
 
-  return r;
+  if (sock == INVALID_SOCKET)
+    {
+      errno = EBADF;
+      return -1;
+    }
+  else
+    {
+      int r = getpeername (sock, addr, addrlen);
+      if (r < 0)
+        set_winsock_errno ();
+
+      return r;
+    }
 }
index 1eabd9496118d2a154a54ddc76d4adf317a29c37..1c494bb98f64d4cd41425d2cc7bcf9dd286f5d9a 100644 (file)
@@ -32,9 +32,18 @@ int
 rpl_getsockname (int fd, struct sockaddr *addr, socklen_t *addrlen)
 {
   SOCKET sock = FD_TO_SOCKET (fd);
-  int r = getsockname (sock, addr, addrlen);
-  if (r < 0)
-    set_winsock_errno ();
 
-  return r;
+  if (sock == INVALID_SOCKET)
+    {
+      errno = EBADF;
+      return -1;
+    }
+  else
+    {
+      int r = getsockname (sock, addr, addrlen);
+      if (r < 0)
+        set_winsock_errno ();
+
+      return r;
+    }
 }
index d82ea5ff218aed463409c2b0bc6f785e018aceba..22176649d95e1c8fce1f663cbc8ef97a6f9b4ea0 100644 (file)
 int
 rpl_getsockopt (int fd, int level, int optname, void *optval, socklen_t *optlen)
 {
-  int r;
   SOCKET sock = FD_TO_SOCKET (fd);
 
-  if (level == SOL_SOCKET && (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO))
+  if (sock == INVALID_SOCKET)
     {
-      int milliseconds;
-      int milliseconds_len = sizeof (int);
-      struct timeval tv;
-      size_t n;
-      r = getsockopt (sock, level, optname, (char *) &milliseconds,
-                      &milliseconds_len);
-      tv.tv_sec = milliseconds / 1000;
-      tv.tv_usec = (milliseconds - 1000 * tv.tv_sec) * 1000;
-      n = sizeof (struct timeval);
-      if (n > *optlen)
-        n = *optlen;
-      memcpy (optval, &tv, n);
-      *optlen = n;
+      errno = EBADF;
+      return -1;
     }
   else
     {
-      r = getsockopt (sock, level, optname, optval, optlen);
-    }
+      int r;
+
+      if (level == SOL_SOCKET
+          && (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO))
+        {
+          int milliseconds;
+          int milliseconds_len = sizeof (int);
+          struct timeval tv;
+          size_t n;
 
-  if (r < 0)
-    set_winsock_errno ();
+          r = getsockopt (sock, level, optname, (char *) &milliseconds,
+                          &milliseconds_len);
+          tv.tv_sec = milliseconds / 1000;
+          tv.tv_usec = (milliseconds - 1000 * tv.tv_sec) * 1000;
+          n = sizeof (struct timeval);
+          if (n > *optlen)
+            n = *optlen;
+          memcpy (optval, &tv, n);
+          *optlen = n;
+        }
+      else
+        {
+          r = getsockopt (sock, level, optname, optval, optlen);
+        }
 
-  return r;
+      if (r < 0)
+        set_winsock_errno ();
+
+      return r;
+    }
 }
index 938aa7546037c43118be56860da5234c5cf6731f..b7d070e64bcde9edc598e1994694cc721bdf1652 100644 (file)
@@ -32,9 +32,18 @@ int
 rpl_listen (int fd, int backlog)
 {
   SOCKET sock = FD_TO_SOCKET (fd);
-  int r = listen (sock, backlog);
-  if (r < 0)
-    set_winsock_errno ();
 
-  return r;
+  if (sock == INVALID_SOCKET)
+    {
+      errno = EBADF;
+      return -1;
+    }
+  else
+    {
+      int r = listen (sock, backlog);
+      if (r < 0)
+        set_winsock_errno ();
+
+      return r;
+    }
 }
index d99b7a40a18d41eef6b1696169ab7b8847b700a7..4755f63709d707473fb6a6fdce0790fb30cb9e49 100644 (file)
@@ -32,9 +32,18 @@ ssize_t
 rpl_recv (int fd, void *buf, size_t len, int flags)
 {
   SOCKET sock = FD_TO_SOCKET (fd);
-  int r = recv (sock, buf, len, flags);
-  if (r < 0)
-    set_winsock_errno ();
 
-  return r;
+  if (sock == INVALID_SOCKET)
+    {
+      errno = EBADF;
+      return -1;
+    }
+  else
+    {
+      int r = recv (sock, buf, len, flags);
+      if (r < 0)
+        set_winsock_errno ();
+
+      return r;
+    }
 }
index 5edd1d8b1c9df7fe79ad87098f997b1b203fe8d4..5ce2b12740de48c1a94778bce3ebfa3c0ee9db97 100644 (file)
@@ -32,17 +32,27 @@ ssize_t
 rpl_recvfrom (int fd, void *buf, size_t len, int flags, struct sockaddr *from,
               socklen_t *fromlen)
 {
-  int frombufsize = (from != NULL ? *fromlen : 0);
   SOCKET sock = FD_TO_SOCKET (fd);
-  int r = recvfrom (sock, buf, len, flags, from, fromlen);
 
-  if (r < 0)
-    set_winsock_errno ();
-
-  /* Winsock recvfrom() only returns a valid 'from' when the socket is
-     connectionless.  POSIX gives a valid 'from' for all types of sockets.  */
-  else if (from != NULL && *fromlen == frombufsize)
-    rpl_getpeername (fd, from, fromlen);
-
-  return r;
+  if (sock == INVALID_SOCKET)
+    {
+      errno = EBADF;
+      return -1;
+    }
+  else
+    {
+      int frombufsize = (from != NULL ? *fromlen : 0);
+      int r = recvfrom (sock, buf, len, flags, from, fromlen);
+
+      if (r < 0)
+        set_winsock_errno ();
+
+      /* Winsock recvfrom() only returns a valid 'from' when the socket is
+         connectionless.  POSIX gives a valid 'from' for all types of
+         sockets.  */
+      else if (from != NULL && *fromlen == frombufsize)
+        rpl_getpeername (fd, from, fromlen);
+
+      return r;
+    }
 }
index d8a876ec3bf3bd8f1f8d65eeab39d0bd1fe636ab..cd21482900635497673b5c39d5d1197cbe1aa260 100644 (file)
@@ -32,9 +32,18 @@ ssize_t
 rpl_send (int fd, const void *buf, size_t len, int flags)
 {
   SOCKET sock = FD_TO_SOCKET (fd);
-  int r = send (sock, buf, len, flags);
-  if (r < 0)
-    set_winsock_errno ();
 
-  return r;
+  if (sock == INVALID_SOCKET)
+    {
+      errno = EBADF;
+      return -1;
+    }
+  else
+    {
+      int r = send (sock, buf, len, flags);
+      if (r < 0)
+        set_winsock_errno ();
+
+      return r;
+    }
 }
index e301626dfb0b2f44e27c09a23e5735117ff59d65..95efab8885635e123cc87431fe43120e67d69ecc 100644 (file)
@@ -33,9 +33,18 @@ rpl_sendto (int fd, const void *buf, size_t len, int flags,
             const struct sockaddr *to, socklen_t tolen)
 {
   SOCKET sock = FD_TO_SOCKET (fd);
-  int r = sendto (sock, buf, len, flags, to, tolen);
-  if (r < 0)
-    set_winsock_errno ();
 
-  return r;
+  if (sock == INVALID_SOCKET)
+    {
+      errno = EBADF;
+      return -1;
+    }
+  else
+    {
+      int r = sendto (sock, buf, len, flags, to, tolen);
+      if (r < 0)
+        set_winsock_errno ();
+
+      return r;
+    }
 }
index a31a10ee92aea53449f3b602eecaa68b39b40f61..6a7ca5e32962892a959cc330e138c54af26ca554 100644 (file)
 int
 rpl_setsockopt (int fd, int level, int optname, const void *optval, socklen_t optlen)
 {
-  int r;
   SOCKET sock = FD_TO_SOCKET (fd);
+  int r;
 
-  if (level == SOL_SOCKET && (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO))
+  if (sock == INVALID_SOCKET)
     {
-      const struct timeval *tv = optval;
-      int milliseconds = tv->tv_sec * 1000 + tv->tv_usec / 1000;
-      optval = &milliseconds;
-      r = setsockopt (sock, level, optname, optval, sizeof (int));
+      errno = EBADF;
+      return -1;
     }
   else
     {
-      r = setsockopt (sock, level, optname, optval, optlen);
-    }
+      if (level == SOL_SOCKET
+          && (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO))
+        {
+          const struct timeval *tv = optval;
+          int milliseconds = tv->tv_sec * 1000 + tv->tv_usec / 1000;
+          optval = &milliseconds;
+          r = setsockopt (sock, level, optname, optval, sizeof (int));
+        }
+      else
+        {
+          r = setsockopt (sock, level, optname, optval, optlen);
+        }
 
-  if (r < 0)
-    set_winsock_errno ();
+      if (r < 0)
+        set_winsock_errno ();
 
-  return r;
+      return r;
+    }
 }
index 26c49323aed7bad81f4b037975f87d0d7fdc91e1..1c302a24f3e5575c22e51a3c8a08c8aec8fe8368 100644 (file)
@@ -32,9 +32,18 @@ int
 rpl_shutdown (int fd, int how)
 {
   SOCKET sock = FD_TO_SOCKET (fd);
-  int r = shutdown (sock, how);
-  if (r < 0)
-    set_winsock_errno ();
 
-  return r;
+  if (sock == INVALID_SOCKET)
+    {
+      errno = EBADF;
+      return -1;
+    }
+  else
+    {
+      int r = shutdown (sock, how);
+      if (r < 0)
+        set_winsock_errno ();
+
+      return r;
+    }
 }