diff src/w32.c @ 45090:c9aa2603d1f7

(sys_getpeername, fcntl): New functions. (_sys_read_ahead): Temporarily block on non-blocking sockets.
author Jason Rumney <jasonr@gnu.org>
date Fri, 03 May 2002 20:40:03 +0000
parents f46982d9ac50
children dd21f49754a1
line wrap: on
line diff
--- a/src/w32.c	Fri May 03 20:35:38 2002 +0000
+++ b/src/w32.c	Fri May 03 20:40:03 2002 +0000
@@ -84,6 +84,7 @@
 #undef gethostname
 #undef gethostbyname
 #undef getservbyname
+#undef getpeername
 #undef shutdown
 #undef setsockopt
 #undef listen
@@ -2424,7 +2425,7 @@
 int (PASCAL *pfn_gethostname) (char * name, int namelen);
 struct hostent * (PASCAL *pfn_gethostbyname) (const char * name);
 struct servent * (PASCAL *pfn_getservbyname) (const char * name, const char * proto);
-
+int (PASCAL *pfn_getpeername) (SOCKET s, struct sockaddr *addr, int * namelen);
 int (PASCAL *pfn_setsockopt) (SOCKET s, int level, int optname,
 			      const char * optval, int optlen);
 int (PASCAL *pfn_listen) (SOCKET s, int backlog);
@@ -2504,6 +2505,7 @@
       LOAD_PROC( gethostname );
       LOAD_PROC( gethostbyname );
       LOAD_PROC( getservbyname );
+      LOAD_PROC( getpeername );
       LOAD_PROC( WSACleanup );
       LOAD_PROC( setsockopt );
       LOAD_PROC( listen );
@@ -2923,6 +2925,28 @@
 }
 
 int
+sys_getpeername (int s, struct sockaddr *addr, int * namelen)
+{
+  if (winsock_lib == NULL)
+    {
+      h_errno = ENETDOWN;
+      return SOCKET_ERROR;
+    }
+
+  check_errno ();
+  if (fd_info[s].flags & FILE_SOCKET)
+    {
+      int rc = pfn_getpeername (SOCK_HANDLE (s), addr, namelen);
+      if (rc == SOCKET_ERROR)
+	set_errno ();
+      return rc;
+    }
+  h_errno = ENOTSOCK;
+  return SOCKET_ERROR;
+}
+
+
+int
 sys_shutdown (int s, int how)
 {
   if (winsock_lib == NULL)
@@ -3074,6 +3098,40 @@
   return SOCKET_ERROR;
 }
 
+/* Windows does not have an fcntl function.  Provide an implementation
+   solely for making sockets non-blocking.  */
+int
+fcntl (int s, int cmd, int options)
+{
+  if (winsock_lib == NULL)
+    {
+      h_errno = ENETDOWN;
+      return -1;
+    }
+
+  check_errno ();
+  if (fd_info[s].flags & FILE_SOCKET)
+    {
+      if (cmd == F_SETFL && options == O_NDELAY)
+	{
+	  unsigned long nblock = 1;
+	  int rc = pfn_ioctlsocket (SOCK_HANDLE (s), FIONBIO, &nblock);
+	  if (rc == SOCKET_ERROR)
+	    set_errno();
+	  /* Keep track of the fact that we set this to non-blocking.  */
+	  fd_info[s].flags |= FILE_NDELAY;
+	  return rc;
+	}
+      else
+	{
+	  h_errno = EINVAL;
+	  return SOCKET_ERROR;
+	}
+    }
+  h_errno = ENOTSOCK;
+  return SOCKET_ERROR;
+}
+
 #endif /* HAVE_SOCKETS */
 
 
@@ -3257,7 +3315,20 @@
     }
 #ifdef HAVE_SOCKETS
   else if (fd_info[fd].flags & FILE_SOCKET)
-    rc = pfn_recv (SOCK_HANDLE (fd), &cp->chr, sizeof (char), 0);
+    {
+      unsigned long nblock = 0;
+      /* We always want this to block, so temporarily disable NDELAY.  */
+      if (fd_info[fd].flags & FILE_NDELAY)
+	pfn_ioctlsocket (SOCK_HANDLE (fd), FIONBIO, &nblock);
+
+      rc = pfn_recv (SOCK_HANDLE (fd), &cp->chr, sizeof (char), 0);
+
+      if (fd_info[fd].flags & FILE_NDELAY)
+	{
+	  nblock = 1;
+	  pfn_ioctlsocket (SOCK_HANDLE (fd), FIONBIO, &nblock);
+	}
+    }
 #endif
   
   if (rc == sizeof (char))