<URL: http://bugs.freeciv.org/Ticket/Display.html?id=21635 >

> [book - Do 05. Okt 2006, 01:29:44]:
> 
> - my_nonblock made to work on win32 (by using ioctlsocket if
>   HAVE_WINSOCK is defined).
> 

I made a similar patch in PR#19481 which covers some more places where
errno got evaluated after a socket function call (which doesn't work
with Winsock). Perhaps you'd like to merge these additional changes into
your netintf patch?
Index: client/clinet.c
===================================================================
--- client/clinet.c	(revision 12328)
+++ client/clinet.c	(working copy)
@@ -1,4 +1,4 @@
-/********************************************************************** 
+/**********************************************************************
  Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -218,8 +218,8 @@
     (void) mystrlcpy(errbuf, mystrerror(), errbufsize);
     my_closesocket(aconnection.sock);
     aconnection.sock = -1;
-#ifdef WIN32_NATIVE
-    return -1;
+#ifdef HAVE_WINSOCK
+    return WSAGetLastError();
 #else
     return errno;
 #endif
@@ -332,7 +332,11 @@
     }
 
     if (n == -1) {
+#ifdef HAVE_WINSOCK
+      if (WSAGetLastError() == WSAEINTR) {
+#else
       if (errno == EINTR) {
+#endif
 	/* EINTR can happen sometimes, especially when compiling with -pg.
 	 * Generally we just want to run select again. */
 	freelog(LOG_DEBUG, "select() returned EINTR");
@@ -448,9 +452,7 @@
 {
   char errbuf[512];
   static int count = 0;
-#ifndef WIN32_NATIVE
   static int warning_shown = 0;
-#endif
 
   if (!autoconnecting) {
     return FC_INFINITY;
@@ -471,9 +473,12 @@
     /* Don't call me again */
     autoconnecting = FALSE;
     return FC_INFINITY;
-#ifndef WIN32_NATIVE
+#ifdef HAVE_WINSOCK
   /* See PR#4042 for more info on issues with try_to_connect() and errno. */
+  case WSAECONNREFUSED:
+#else
   case ECONNREFUSED:		/* Server not available (yet) */
+#endif
     if (!warning_shown) {
       freelog(LOG_NORMAL, _("Connection to server refused. "
 			    "Please start the server."));
@@ -483,7 +488,6 @@
     }
     /* Try again in 0.5 seconds */
     return 0.001 * AUTOCONNECT_INTERVAL;
-#endif
   default:			/* All other errors are fatal */
     freelog(LOG_FATAL,
 	    _("Error contacting server \"%s\" at port %d "
Index: client/gui-sdl/gui_main.c
===================================================================
--- client/gui-sdl/gui_main.c	(revision 12328)
+++ client/gui-sdl/gui_main.c	(working copy)
@@ -562,7 +562,11 @@
     
       result = select(net_socket + 1, &civfdset, NULL, NULL, &tv);
       if(result < 0) {
+#ifdef HAVE_WINSOCK
+        if (WSAGetLastError() != WSAEINTR) {
+#else
         if (errno != EINTR) {
+#endif
 	  break;
         } else {
 	  continue;
Index: client/servers.c
===================================================================
--- client/servers.c	(revision 12328)
+++ client/servers.c	(working copy)
@@ -350,7 +350,11 @@
     result = my_readsocket(scan->sock, buf, sizeof(buf));
 
     if (result < 0) {
+#ifdef HAVE_WINSOCK
+      if (WSAGetLastError() == WSAEINTR) {
+#else
       if (errno == EAGAIN || errno == EINTR) {
+#endif
 	/* Keep waiting. */
 	return;
       }
@@ -422,13 +426,11 @@
   my_nonblock(s);
   
   if (connect(s, (struct sockaddr *) &addr.sockaddr, sizeof(addr)) == -1) {
-    if (
 #ifdef HAVE_WINSOCK
-	errno == WSAEINPROGRESS
+    if ((WSAGetLastError() == WSAEWOULDBLOCK) || (WSAGetLastError() == WSAEINPROGRESS)) {
 #else
-	errno == EINPROGRESS
+    if (errno == EINPROGRESS) {
 #endif
-	) {
       /* With non-blocking sockets this is the expected result. */
       scan->meta.state = META_CONNECTING;
       scan->sock = s;
@@ -542,8 +544,10 @@
   unsigned char buffer[MAX_LEN_PACKET];
   struct ip_mreq mreq;
   const char *group;
+  size_t size;
+#ifndef HAVE_WINSOCK
   unsigned char ttl;
-  size_t size;
+#endif
 
   /* Create a socket for broadcasting to servers. */
   if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
@@ -563,13 +567,17 @@
   addr.sockaddr_in.sin_addr.s_addr = inet_addr(get_multicast_group());
   addr.sockaddr_in.sin_port = htons(SERVER_LAN_PORT);
 
+/* this setsockopt call fails on Windows 98, so we stick with the default
+ * value of 1 which should be fine in most cases */
+#ifndef HAVE_WINSOCK
   /* Set the Time-to-Live field for the packet  */
   ttl = SERVER_LAN_TTL;
-  if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, 
+  if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl,
                  sizeof(ttl))) {
     freelog(LOG_ERROR, "setsockopt failed: %s", mystrerror());
     return FALSE;
   }
+#endif
 
   if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&opt, 
                  sizeof(opt))) {
Index: common/connection.c
===================================================================
--- common/connection.c	(revision 12328)
+++ common/connection.c	(working copy)
@@ -174,7 +174,11 @@
     return -1;
   }
 #ifdef NONBLOCKING_SOCKETS
+#ifdef HAVE_WINSOCK
+  else if (WSAGetLastError() == WSAEWOULDBLOCK) {
+#else
   else if (errno == EWOULDBLOCK || errno == EAGAIN) {
+#endif
     freelog(LOG_DEBUG, "EGAIN on socket read");
     return 0;
   }
@@ -213,7 +217,11 @@
     tv.tv_sec = 0; tv.tv_usec = 0;
 
     if (select(pc->sock+1, NULL, &writefs, &exceptfs, &tv) <= 0) {
+#ifdef HAVE_WINSOCK
+      if (WSAGetLastError() != WSAEINTR) {
+#else
       if (errno != EINTR) {
+#endif
 	break;
       } else {
 	/* EINTR can happen sometimes, especially when compiling with -pg.
@@ -240,7 +248,11 @@
       if((nput=my_writesocket(pc->sock, 
 			      (const char *)buf->data+start, nblock)) == -1) {
 #ifdef NONBLOCKING_SOCKETS
+#ifdef HAVE_WINSOCK
+	if (WSAGetLastError() == WSAEWOULDBLOCK) {
+#else
 	if (errno == EWOULDBLOCK || errno == EAGAIN) {
+#endif
 	  break;
 	}
 #endif
Index: configure.ac
===================================================================
--- configure.ac	(revision 12328)
+++ configure.ac	(working copy)
@@ -337,6 +337,7 @@
   AC_DEFINE(ALWAYS_ROOT, 1, [Mingw32-specific setting - root])
   AC_DEFINE(WIN32_NATIVE, 1, [Mingw32-specific setting - native])
   AC_DEFINE(HAVE_WINSOCK, 1, [Mingw32-specific setting - winsock])
+  AC_DEFINE(NONBLOCKING_SOCKETS, 1, [nonblocking sockets support])
   LIBS="$LIBS -lwsock32"
 fi
 
Index: server/sernet.c
===================================================================
--- server/sernet.c	(revision 12328)
+++ server/sernet.c	(working copy)
@@ -1,4 +1,4 @@
-/********************************************************************** 
+/**********************************************************************
  Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -1088,7 +1088,11 @@
   tv.tv_usec = 0;
 
   while (select(socklan + 1, &readfs, NULL, &exceptfs, &tv) == -1) {
+#ifdef HAVE_WINSOCK
+    if (WSAGetLastError() != WSAEINTR) {
+#else
     if (errno != EINTR) {
+#endif
       freelog(LOG_ERROR, "select failed: %s", mystrerror());
       return;
     }
@@ -1128,7 +1132,9 @@
   int socksend, setting = 1;
   const char *group;
   size_t size;
+#ifndef HAVE_WINSOCK
   unsigned char ttl;
+#endif
 
   /* Create a socket to broadcast to client. */
   if ((socksend = socket(AF_INET,SOCK_DGRAM, 0)) < 0) {
@@ -1143,15 +1149,19 @@
   addr.sockaddr_in.sin_addr.s_addr = inet_addr(group);
   addr.sockaddr_in.sin_port = htons(SERVER_LAN_PORT + 1);
 
+/* this setsockopt call fails on Windows 98, so we stick with the default
+ * value of 1 which should be fine in most cases */
+#ifndef HAVE_WINSOCK
   /* Set the Time-to-Live field for the packet.  */
   ttl = SERVER_LAN_TTL;
-  if (setsockopt(socksend, IPPROTO_IP, IP_MULTICAST_TTL, 
+  if (setsockopt(socksend, IPPROTO_IP, IP_MULTICAST_TTL,
                  (const char*)&ttl, sizeof(ttl))) {
     freelog(LOG_ERROR, "setsockopt failed: %s", mystrerror());
     return;
   }
+#endif
 
-  if (setsockopt(socksend, SOL_SOCKET, SO_BROADCAST, 
+  if (setsockopt(socksend, SOL_SOCKET, SO_BROADCAST,
                  (const char*)&setting, sizeof(setting))) {
     freelog(LOG_ERROR, "setsockopt failed: %s", mystrerror());
     return;
Index: utility/ftwl/be_x11_ximage.c
===================================================================
--- utility/ftwl/be_x11_ximage.c	(revision 12328)
+++ utility/ftwl/be_x11_ximage.c	(working copy)
@@ -276,7 +276,11 @@
      * New data on the x11 fd. return with BE_NO_EVENT and let the
      * caller handle it. 
      */
+#ifdef HAVE_WINSOCK
+  } else if (WSAGetLastError() == WSAEINTR) {
+#else
   } else if (errno == EINTR) {
+#endif
     goto restart;
   } else {
     assert(0);
Index: utility/netintf.c
===================================================================
--- utility/netintf.c	(revision 12328)
+++ utility/netintf.c	(working copy)
@@ -132,6 +132,10 @@
 void my_nonblock(int sockfd)
 {
 #ifdef NONBLOCKING_SOCKETS
+#ifdef HAVE_WINSOCK
+  unsigned long b = 1;
+  ioctlsocket(sockfd, FIONBIO, &b);
+#else
 #ifdef HAVE_FCNTL
   int f_set;
 
@@ -153,6 +157,7 @@
   }
 #endif
 #endif
+#endif
 #else
   freelog(LOG_DEBUG, "NONBLOCKING_SOCKETS not available");
 #endif
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to