]> code.delx.au - gnu-emacs/commitdiff
(init_winsock): Dynamically link to SetHandleInformation.
authorRichard M. Stallman <rms@gnu.org>
Thu, 6 Jun 1996 17:07:00 +0000 (17:07 +0000)
committerRichard M. Stallman <rms@gnu.org>
Thu, 6 Jun 1996 17:07:00 +0000 (17:07 +0000)
(sys_socket): If possible, use SetHandleInformation to make socket
handle non-inheritable to avoid a bug in NT.

src/w32.c

index e304523646556b43dd6377957d376d0aba2779e9..7e9f59d1ae5f0a79e8d9397a86d220884aba63b8 100644 (file)
--- a/src/w32.c
+++ b/src/w32.c
@@ -1338,6 +1338,12 @@ unsigned long (PASCAL *pfn_inet_addr) (const char * cp);
 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);
+  
+/* SetHandleInformation is only needed to make sockets non-inheritable. */
+BOOL (WINAPI *pfn_SetHandleInformation) (HANDLE object, DWORD mask, DWORD flags);
+#ifndef HANDLE_FLAG_INHERIT
+#define HANDLE_FLAG_INHERIT    1
+#endif
 
 static int have_winsock;
 static HANDLE winsock_lib;
@@ -1357,6 +1363,13 @@ init_winsock ()
 {
   WSADATA  winsockData;
 
+  have_winsock = FALSE;
+
+  pfn_SetHandleInformation = NULL;
+  pfn_SetHandleInformation
+    = (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"),
+                              "SetHandleInformation");
+
   winsock_lib = LoadLibrary ("wsock32.dll");
 
   if (winsock_lib != NULL)
@@ -1396,7 +1409,6 @@ init_winsock ()
     fail:
       FreeLibrary (winsock_lib);
     }
-  have_winsock = FALSE;
 }
 
 
@@ -1488,16 +1500,27 @@ sys_socket(int af, int type, int protocol)
 
            parent = GetCurrentProcess ();
 
-           DuplicateHandle (parent,
-                            (HANDLE) s,
-                            parent,
-                            &new_s,
-                            0,
-                            FALSE,
-                            DUPLICATE_SAME_ACCESS);
-           pfn_closesocket (s);
-           fd_info[fd].hnd = new_s;
-           s = (SOCKET) new_s;
+           /* Apparently there is a bug in NT 3.51 with some service
+              packs, which prevents using DuplicateHandle to make a
+              socket handle non-inheritable (causes WSACleanup to
+              hang).  The work-around is to use SetHandleInformation
+              instead if it is available and implemented. */
+           if (!pfn_SetHandleInformation
+               || !pfn_SetHandleInformation ((HANDLE) s,
+                                             HANDLE_FLAG_INHERIT,
+                                             HANDLE_FLAG_INHERIT))
+             {
+               DuplicateHandle (parent,
+                                (HANDLE) s,
+                                parent,
+                                &new_s,
+                                0,
+                                FALSE,
+                                DUPLICATE_SAME_ACCESS);
+               pfn_closesocket (s);
+               s = (SOCKET) new_s;
+             }
+           fd_info[fd].hnd = (HANDLE) s;
          }
 #endif