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 a653b15..542c6fa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
 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.
        * tests/test-select.h (do_select_bad_fd, do_select_bad_fd_nowait,
        test_bad_fd): New functions.
index 5591fa5..01faf54 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 e6d959d..baaea59 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 ea03e77..afd13b9 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 9e540a1..abe5a40 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 1eabd94..1c494bb 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 d82ea5f..2217664 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 938aa75..b7d070e 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 d99b7a4..4755f63 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 5edd1d8..5ce2b12 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 d8a876e..cd21482 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 e301626..95efab8 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 a31a10e..6a7ca5e 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 26c4932..1c302a2 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;
+    }
 }