bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: getting EBADF on mingw


From: Bruno Haible
Subject: Re: getting EBADF on mingw
Date: Wed, 21 Sep 2011 00:23:55 +0200
User-agent: KMail/1.13.6 (Linux/2.6.37.6-0.5-desktop; KDE/4.6.0; x86_64; ; )

I wrote:
> I've added such tests for 'accept' and 'accept4'. More such tests are to come
> for:
> 
>   bind
>   close
>   connect
>   dprintf
>   dup
>   dup2
>   faccessat
>   fchdir
>   fchmod
>   fchown
>   fclose
>   fcntl
>   fdatasync
>   fdopen
>   fdopendir
>   fdutimensat
>   fflush
>   fgetc
>   fputc
>   freopen
>   fseeko
>   fstat
>   fsync
>   ftello
>   ftruncate
>   futimens
>   getpeername
>   getsockname
>   getsockopt
>   grantpt
>   ioctl
>   isatty
>   linkat
>   listen
>   lseek
>   mkfifoat
>   openat
>   posix_spawn_file_actions_addclose
>   posix_spawn_file_actions_adddup2
>   posix_spawn_file_actions_addopen
>   pread
>   pwrite
>   read
>   readlinkat
>   recv
>   recvfrom
>   renameat
>   select
>   send
>   sendto
>   setsockopt
>   shutdown
>   symlinkat
>   ttyname_r
>   unlockpt
>   utimens
>   utimensat
>   vdprintf
>   write

I've added these tests now. On mingw, I got test failures for the socket
functions:

test-accept.c:42: assertion failed
FAIL: test-accept.exe

test-bind.c:46: assertion failed
FAIL: test-bind.exe

test-connect.c:47: assertion failed
FAIL: test-connect.exe

test-getpeername.c:42: assertion failed
FAIL: test-getpeername.exe

test-getsockname.c:42: assertion failed
FAIL: test-getsockname.exe

test-getsockopt.c:42: assertion failed
FAIL: test-getsockopt.exe

test-listen.c:38: assertion failed
FAIL: test-listen.exe

test-recv.c:39: assertion failed
FAIL: test-recv.exe

test-recvfrom.c:46: assertion failed
FAIL: test-recvfrom.exe

test-send.c:39: assertion failed
FAIL: test-send.exe

test-sendto.c:51: assertion failed
FAIL: test-sendto.exe

test-setsockopt.c:41: assertion failed
FAIL: test-setsockopt.exe

test-shutdown.c:38: assertion failed
FAIL: test-shutdown.exe


This fixes it.


2011-09-20  Bruno Haible  <address@hidden>

        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.

diff --git a/lib/accept.c b/lib/accept.c
*** a/lib/accept.c
--- b/lib/accept.c
***************
*** 31,42 ****
  int
  rpl_accept (int fd, struct sockaddr *addr, socklen_t *addrlen)
  {
!   SOCKET fh = accept (FD_TO_SOCKET (fd), addr, addrlen);
!   if (fh == INVALID_SOCKET)
      {
!       set_winsock_errno ();
        return -1;
      }
    else
!     return SOCKET_TO_FD (fh);
  }
--- 31,52 ----
  int
  rpl_accept (int fd, struct sockaddr *addr, socklen_t *addrlen)
  {
!   SOCKET sock = FD_TO_SOCKET (fd);
! 
!   if (sock == INVALID_SOCKET)
      {
!       errno = EBADF;
        return -1;
      }
    else
!     {
!       SOCKET fh = accept (sock, addr, addrlen);
!       if (fh == INVALID_SOCKET)
!         {
!           set_winsock_errno ();
!           return -1;
!         }
!       else
!         return SOCKET_TO_FD (fh);
!     }
  }
diff --git a/lib/bind.c b/lib/bind.c
*** a/lib/bind.c
--- b/lib/bind.c
***************
*** 32,40 ****
  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;
  }
--- 32,49 ----
  rpl_bind (int fd, const struct sockaddr *sockaddr, socklen_t len)
  {
    SOCKET sock = FD_TO_SOCKET (fd);
  
!   if (sock == INVALID_SOCKET)
!     {
!       errno = EBADF;
!       return -1;
!     }
!   else
!     {
!       int r = bind (sock, sockaddr, len);
!       if (r < 0)
!         set_winsock_errno ();
! 
!       return r;
!     }
  }
diff --git a/lib/connect.c b/lib/connect.c
*** a/lib/connect.c
--- b/lib/connect.c
***************
*** 32,47 ****
  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 ();
      }
- 
-   return r;
  }
--- 32,56 ----
  rpl_connect (int fd, const struct sockaddr *sockaddr, socklen_t len)
  {
    SOCKET sock = FD_TO_SOCKET (fd);
  
!   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;
      }
  }
diff --git a/lib/getpeername.c b/lib/getpeername.c
*** a/lib/getpeername.c
--- b/lib/getpeername.c
***************
*** 32,40 ****
  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;
  }
--- 32,49 ----
  rpl_getpeername (int fd, struct sockaddr *addr, socklen_t *addrlen)
  {
    SOCKET sock = FD_TO_SOCKET (fd);
  
!   if (sock == INVALID_SOCKET)
!     {
!       errno = EBADF;
!       return -1;
!     }
!   else
!     {
!       int r = getpeername (sock, addr, addrlen);
!       if (r < 0)
!         set_winsock_errno ();
! 
!       return r;
!     }
  }
diff --git a/lib/getsockname.c b/lib/getsockname.c
*** a/lib/getsockname.c
--- b/lib/getsockname.c
***************
*** 32,40 ****
  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;
  }
--- 32,49 ----
  rpl_getsockname (int fd, struct sockaddr *addr, socklen_t *addrlen)
  {
    SOCKET sock = FD_TO_SOCKET (fd);
  
!   if (sock == INVALID_SOCKET)
!     {
!       errno = EBADF;
!       return -1;
!     }
!   else
!     {
!       int r = getsockname (sock, addr, addrlen);
!       if (r < 0)
!         set_winsock_errno ();
! 
!       return r;
!     }
  }
diff --git a/lib/getsockopt.c b/lib/getsockopt.c
*** a/lib/getsockopt.c
--- b/lib/getsockopt.c
***************
*** 37,68 ****
  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))
      {
!       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;
      }
    else
      {
!       r = getsockopt (sock, level, optname, optval, optlen);
!     }
  
!   if (r < 0)
!     set_winsock_errno ();
  
!   return r;
  }
--- 37,79 ----
  int
  rpl_getsockopt (int fd, int level, int optname, void *optval, socklen_t 
*optlen)
  {
    SOCKET sock = FD_TO_SOCKET (fd);
  
!   if (sock == INVALID_SOCKET)
      {
!       errno = EBADF;
!       return -1;
      }
    else
      {
!       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;
  
!           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);
!         }
  
!       if (r < 0)
!         set_winsock_errno ();
! 
!       return r;
!     }
  }
diff --git a/lib/listen.c b/lib/listen.c
*** a/lib/listen.c
--- b/lib/listen.c
***************
*** 32,40 ****
  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;
  }
--- 32,49 ----
  rpl_listen (int fd, int backlog)
  {
    SOCKET sock = FD_TO_SOCKET (fd);
  
!   if (sock == INVALID_SOCKET)
!     {
!       errno = EBADF;
!       return -1;
!     }
!   else
!     {
!       int r = listen (sock, backlog);
!       if (r < 0)
!         set_winsock_errno ();
! 
!       return r;
!     }
  }
diff --git a/lib/recv.c b/lib/recv.c
*** a/lib/recv.c
--- b/lib/recv.c
***************
*** 32,40 ****
  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;
  }
--- 32,49 ----
  rpl_recv (int fd, void *buf, size_t len, int flags)
  {
    SOCKET sock = FD_TO_SOCKET (fd);
  
!   if (sock == INVALID_SOCKET)
!     {
!       errno = EBADF;
!       return -1;
!     }
!   else
!     {
!       int r = recv (sock, buf, len, flags);
!       if (r < 0)
!         set_winsock_errno ();
! 
!       return r;
!     }
  }
diff --git a/lib/recvfrom.c b/lib/recvfrom.c
*** a/lib/recvfrom.c
--- b/lib/recvfrom.c
***************
*** 32,48 ****
  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;
  }
--- 32,58 ----
  rpl_recvfrom (int fd, void *buf, size_t len, int flags, struct sockaddr *from,
                socklen_t *fromlen)
  {
    SOCKET sock = FD_TO_SOCKET (fd);
  
!   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;
!     }
  }
diff --git a/lib/send.c b/lib/send.c
*** a/lib/send.c
--- b/lib/send.c
***************
*** 32,40 ****
  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;
  }
--- 32,49 ----
  rpl_send (int fd, const void *buf, size_t len, int flags)
  {
    SOCKET sock = FD_TO_SOCKET (fd);
  
!   if (sock == INVALID_SOCKET)
!     {
!       errno = EBADF;
!       return -1;
!     }
!   else
!     {
!       int r = send (sock, buf, len, flags);
!       if (r < 0)
!         set_winsock_errno ();
! 
!       return r;
!     }
  }
diff --git a/lib/sendto.c b/lib/sendto.c
*** a/lib/sendto.c
--- b/lib/sendto.c
***************
*** 33,41 ****
              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;
  }
--- 33,50 ----
              const struct sockaddr *to, socklen_t tolen)
  {
    SOCKET sock = FD_TO_SOCKET (fd);
  
!   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;
!     }
  }
diff --git a/lib/setsockopt.c b/lib/setsockopt.c
*** a/lib/setsockopt.c
--- b/lib/setsockopt.c
***************
*** 34,56 ****
  int
  rpl_setsockopt (int fd, int level, int optname, const void *optval, socklen_t 
optlen)
  {
-   int r;
    SOCKET sock = FD_TO_SOCKET (fd);
  
!   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 ();
  
!   return r;
  }
--- 34,65 ----
  int
  rpl_setsockopt (int fd, int level, int optname, const void *optval, socklen_t 
optlen)
  {
    SOCKET sock = FD_TO_SOCKET (fd);
+   int r;
  
!   if (sock == INVALID_SOCKET)
      {
!       errno = EBADF;
!       return -1;
      }
    else
      {
!       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 ();
  
!       return r;
!     }
  }
diff --git a/lib/shutdown.c b/lib/shutdown.c
*** a/lib/shutdown.c
--- b/lib/shutdown.c
***************
*** 32,40 ****
  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;
  }
--- 32,49 ----
  rpl_shutdown (int fd, int how)
  {
    SOCKET sock = FD_TO_SOCKET (fd);
  
!   if (sock == INVALID_SOCKET)
!     {
!       errno = EBADF;
!       return -1;
!     }
!   else
!     {
!       int r = shutdown (sock, how);
!       if (r < 0)
!         set_winsock_errno ();
! 
!       return r;
!     }
  }

-- 
In memoriam Pierre Goldman <http://en.wikipedia.org/wiki/Pierre_Goldman>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]