Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

socket() call uses non-IFS providers causing subsequent print/read to hang or misbehave #6860

Closed
p5pRT opened this issue Oct 22, 2003 · 11 comments

Comments

@p5pRT
Copy link

p5pRT commented Oct 22, 2003

Migrated from rt.perl.org#24269 (status was 'resolved')

Searchable as RT24269$

@p5pRT
Copy link
Author

p5pRT commented Oct 22, 2003

From apm@atwss.com

Created by apm@prog8

This is a bug report for perl from apm@​prog8,
generated with the help of perlbug 1.34 running under perl v5.8.1.

-----------------------------------------------------------------
How to reproduce​:
1) install any non-IFS layered service provider on WinNT/Win2k/WinXP.
  You can get sample LSP from MS Platform SDK
2) run sample TCP/IP client and server from "perldoc perlipc"
3) server and client hang. This is NOT a bug in sample perl code

Desired result​:
client prints server's response AND quits

Problem description​:
socket() call selects first suitable service provider for given
address family/proto type/etc. non-IFS is selected first if it's
installed. Next, you set SO_SYNCHRONOUS_NONALERT on socket and then
call print. The thing is that print (WriteFile() in win32) is
mapped to overlapped WSPSend() on socket, but it's not possible
to use overlapped IO after SO_SYNCHRONOUS_NONALERT unless
provider is IFS-compatible.

Fix​:
socket() should be replaced with WSASocket() and provider lookup
must be done to find IFS-compatible provider. It's known for sure
that at least one provider (MSAFD) has IFS support.

Patch​:

Inline Patch
diff -ruN perl-5.8.1/win32/Makefile perl-5.8.1-new/win32/Makefile
--- perl-5.8.1/win32/Makefile	Thu Sep 25 14:14:19 2003
+++ perl-5.8.1-new/win32/Makefile	Thu Oct 23 10:19:49 2003
@@ -326,7 +326,7 @@


  # VC 6.0 can load the socket dll on demand.  Makes the test suite

  # run in about 10% less time.

-DELAYLOAD	= -DELAYLOAD:wsock32.dll -DELAYLOAD:shell32.dll delayimp.lib

+DELAYLOAD	= -DELAYLOAD:ws2_32.dll -DELAYLOAD:shell32.dll delayimp.lib

  !ENDIF



  ARCHDIR		= ..\lib\$(ARCHNAME)

@@ -408,7 +408,7 @@
  LIBBASEFILES	= $(CRYPT_LIB) \

  		oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib \

  		comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \

-		netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib \

+		netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib \

  		version.lib



  # win64 doesn't have some libs

diff -ruN perl-5.8.1/win32/win32sck.c perl-5.8.1-new/win32/win32sck.c
--- perl-5.8.1/win32/win32sck.c	Tue Sep  2 16:42:10 2003
+++ perl-5.8.1-new/win32/win32sck.c	Wed Oct 22 16:03:40 2003
@@ -16,6 +16,11 @@
  #define Win32_Winsock
  #endif
  #include <windows.h>
+#include <ws2spi.h>
+/* winsock2.h overrides winsock.h but does not include the following*/
+#define SO_SYNCHRONOUS_NONALERT 0x20
+#define SO_OPENTYPE     0x7008
+
  #include "EXTERN.h"
  #include "perl.h"

@@ -399,6 +404,63 @@
      return r;
  }

+#ifdef USE_SOCKETS_AS_HANDLES
+#define WIN32_OPEN_SOCKET(af, type, protocol) open_ifs_socket(af, type, 
protocol) \+ \+void \+convert\_proto\_info\_w2a\(WSAPROTOCOL\_INFOW \*in\, WSAPROTOCOL\_INFOA \*out\) \+\{ \+ memcpy\(out\, in\, sizeof\(WSAPROTOCOL\_INFOA\)\); \+ wcstombs\(out\->szProtocol\, in\->szProtocol\, sizeof\(out\->szProtocol\)\); \+\} \+ \+SOCKET \+open\_ifs\_socket\(int af\, int type\, int protocol\) \+\{ \+ unsigned long proto\_buffers\_len = 0; \+ int error\_code; \+ SOCKET out = INVALID\_SOCKET; \+ \+ if \(WSCEnumProtocols\(NULL\, NULL\, &proto\_buffers\_len\, &error\_code\) == SOCKET\_ERROR \+ && error\_code == WSAENOBUFS\) \+ \{ \+ WSAPROTOCOL\_INFOW \*proto\_buffers = \(WSAPROTOCOL\_INFOW \*\) malloc\(proto\_buffers\_len\); \+ int protocols\_available = 0; \+ \+ if \(\(protocols\_available = WSCEnumProtocols\(NULL\, proto\_buffers\, \+ &proto\_buffers\_len\, &error\_code\)\) \!= SOCKET\_ERROR\) \+ \{ \+ int i; \+ for \(i = 0; i \< protocols\_available; i\+\+\) \+ \{ \+ WSAPROTOCOL\_INFOA proto\_info; \+ \+ if \(\(af \!= AF\_UNSPEC && af \!= proto\_buffers\[i\]\.iAddressFamily\) \+ || \(type \!= proto\_buffers\[i\]\.iSocketType\) \+ || \(protocol \!= 0 && protocol \!= proto\_buffers\[i\]\.iProtocol\)\) \+ continue; \+ \+ if \(\(proto\_buffers\[i\]\.dwServiceFlags1 & XP1\_IFS\_HANDLES\) == 0\) \+ continue; \+ \+ convert\_proto\_info\_w2a\(&\(proto\_buffers\[i\]\)\, &proto\_info\); \+ \+ out = WSASocket\(af\, type\, protocol\, &proto\_info\, 0\, 0\); \+ break; \+ \} \+ \} \+ \+ if \(proto\_buffers\) \+ free\(proto\_buffers\); \+ \} \+ \+ return out; \+\} \+ \+\#else \+\#define WIN32\_OPEN\_SOCKET\(af\, type\, protocol\) socket\(af\, type\, protocol\) \+\#endif \+   SOCKET   win32\_socket\(int af\, int type\, int protocol\)   \{ @​@​ \-408\,7 \+470\,8 @​@​   SOCKET\_TEST\(s = socket\(af\, type\, protocol\)\, INVALID\_SOCKET\);   \#else   StartSockets\(\); \- if\(\(s = socket\(af\, type\, protocol\)\) == INVALID\_SOCKET\) \+ \+ if\(\(s = WIN32\_OPEN\_SOCKET\(af\, type\, protocol\)\) == INVALID\_SOCKET\)   errno = WSAGetLastError\(\);   else   s = OPEN\_SOCKET\(s\); \-\-\-\(cut\)\-\-\-
Perl Info

Flags:
     category=core
     severity=medium

Site configuration information for perl v5.8.1:

Configured by apm at Wed Oct 22 12:26:52 2003.

Summary of my perl5 (revision 5 version 8 subversion 1) configuration:
   Platform:
     osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread
     uname=''
     config_args='undef'
     hint=recommended, useposix=true, d_sigaction=undef
     usethreads=undef use5005threads=undef useithreads=define 
usemultiplicity=define
     useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
     use64bitint=undef use64bitall=undef uselongdouble=undef
     usemymalloc=n, bincompat5005=undef
   Compiler:
     cc='cl', ccflags ='-nologo -Gf -W3 -Od -MD -Zi -DDEBUGGING -DWIN32 
-D_CONSOLE -DNO_STRICT   -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS 
-DUSE_PERLIO -DPERL_MSVCRT_READFIX',
     optimize='-Od -MD -Zi -DDEBUGGING',
     cppflags='-DWIN32'
     ccversion='', gccversion='', gccosandvers=''
     intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
     d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10
     ivtype='long', ivsize=4, nvtype='double', nvsize=8, 
Off_t='__int64', lseeksize=8
     alignbytes=8, prototype=define
   Linker and Libraries:
     ld='link', ldflags ='-nologo -nodefaultlib -debug 
-libpath:"f:\temp\perl\lib\CORE"  -machine:x86'
     libpth="c:\program files\microsoft visual studio\vc98\lib"
     libs=  oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib 
  comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib 
netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib  version.lib 
odbc32.lib odbccp32.lib msvcrt.lib
     perllibs=  oldnames.lib kernel32.lib user32.lib gdi32.lib 
winspool.lib  comdlg32.lib advapi32.lib shell32.lib ole32.lib 
oleaut32.lib  netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib 
version.lib odbc32.lib odbccp32.lib msvcrt.lib
     libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl58.lib
     gnulibc_version='undef'
   Dynamic Linking:
     dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
     cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug 
-libpath:"f:\temp\perl\lib\CORE"  -machine:x86'

Locally applied patches:



@INC for perl v5.8.1:
     F:/tmp/perl-5.8.1/lib
     .


Environment for perl v5.8.1:
     CYGWIN=tty
     HOME (unset)
     LANG (unset)
     LANGUAGE (unset)
     LD_LIBRARY_PATH (unset)
     LOGDIR (unset)
     PATH=F:\tmp\perl-5.8.1;C:\Program 
Files\Far;C:\Python22\.;C:\Tcl\bin;e:\texmf\miktex\bin\;C:\Perl\bin;C:\WINNT\system32;C:\WINNT;C:\WINNT\System32\Wbem;C:\Program 
Files\doxygen\bin;C:\PROGRA~1\ATT\Graphviz\bin;C:\PROGRA~1\ATT\Graphviz\bin\tools;e:\Program 
Files\Rational\common;C:\program files\wise installation 
system;C:\Program Files\Rational\Quantify;C:\Program 
Files\Rational\Quantify\cache
     PERL_BADLANG (unset)
     SHELL (unset)



@p5pRT
Copy link
Author

p5pRT commented Jul 28, 2004

From artiom@phreaker.net

Attached is the patch redone based on Steve Hay's
<steve.hay@​uk.radan.com> comments. It removes call to setsockopt with
deprecated SO_OPENTYPE level.

@p5pRT
Copy link
Author

p5pRT commented Jul 28, 2004

From artiom@phreaker.net

perl-5.8.1.patch
diff -rdu perl-5.8.1-old/win32/Makefile perl-5.8.1/win32/Makefile
--- perl-5.8.1-old/win32/Makefile	2004-07-28 20:34:46.000000000 +0300
+++ perl-5.8.1/win32/Makefile	2003-10-22 16:11:16.000000000 +0300
@@ -326,7 +326,7 @@
 
 # VC 6.0 can load the socket dll on demand.  Makes the test suite
 # run in about 10% less time.
-DELAYLOAD	= -DELAYLOAD:wsock32.dll -DELAYLOAD:shell32.dll delayimp.lib
+DELAYLOAD	= -DELAYLOAD:ws2_32.dll -DELAYLOAD:shell32.dll delayimp.lib
 !ENDIF
 
 ARCHDIR		= ..\lib\$(ARCHNAME)
@@ -408,7 +408,7 @@
 LIBBASEFILES	= $(CRYPT_LIB) \
 		oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib \
 		comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \
-		netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib \
+		netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib \
 		version.lib
 
 # win64 doesn't have some libs
diff -rdu perl-5.8.1-old/win32/win32.c perl-5.8.1/win32/win32.c
--- perl-5.8.1-old/win32/win32.c	2004-07-28 20:34:48.000000000 +0300
+++ perl-5.8.1/win32/win32.c	2004-07-28 20:37:50.000000000 +0300
@@ -5033,7 +5033,6 @@
     New(1313, w32_pseudo_children, 1, child_tab);
     w32_num_pseudo_children	= 0;
 #  endif
-    w32_init_socktype		= 0;
     w32_timerid                 = 0;
     w32_poll_count              = 0;
     for (i=0; i < SIG_SIZE; i++) {
@@ -5087,7 +5086,6 @@
     Newz(1313, dst->children, 1, child_tab);
     dst->pseudo_id		= 0;
     Newz(1313, dst->pseudo_children, 1, child_tab);
-    dst->thr_intern.Winit_socktype = 0;
     dst->timerid                 = 0;
     dst->poll_count              = 0;
     Copy(src->sigtable,dst->sigtable,SIG_SIZE,Sighandler_t);
diff -rdu perl-5.8.1-old/win32/win32.h perl-5.8.1/win32/win32.h
--- perl-5.8.1-old/win32/win32.h	2004-07-28 20:34:48.000000000 +0300
+++ perl-5.8.1/win32/win32.h	2004-07-28 20:37:42.000000000 +0300
@@ -358,9 +358,6 @@
     char		Wstrerror_buffer[512];
     struct servent	Wservent;
     char		Wgetlogin_buffer[128];
-#    ifdef USE_SOCKETS_AS_HANDLES
-    int			Winit_socktype;
-#    endif
 #    ifdef HAVE_DES_FCRYPT
     char		Wcrypt_buffer[30];
 #    endif
@@ -436,7 +433,6 @@
 #  define w32_getlogin_buffer	(thr->i.Wgetlogin_buffer)
 #  define w32_crypt_buffer	(thr->i.Wcrypt_buffer)
 #  define w32_servent		(thr->i.Wservent)
-#  define w32_init_socktype	(thr->i.Winit_socktype)
 #  define w32_use_showwindow	(thr->i.Wuse_showwindow)
 #  define w32_showwindow	(thr->i.Wshowwindow)
 #else
@@ -444,7 +440,6 @@
 #  define w32_getlogin_buffer	(PL_sys_intern.thr_intern.Wgetlogin_buffer)
 #  define w32_crypt_buffer	(PL_sys_intern.thr_intern.Wcrypt_buffer)
 #  define w32_servent		(PL_sys_intern.thr_intern.Wservent)
-#  define w32_init_socktype	(PL_sys_intern.thr_intern.Winit_socktype)
 #  define w32_use_showwindow	(PL_sys_intern.thr_intern.Wuse_showwindow)
 #  define w32_showwindow	(PL_sys_intern.thr_intern.Wshowwindow)
 #endif /* USE_5005THREADS */
Only in perl-5.8.1/win32: win32.obj
Only in perl-5.8.1/win32: win32io.obj
diff -rdu perl-5.8.1-old/win32/win32sck.c perl-5.8.1/win32/win32sck.c
--- perl-5.8.1-old/win32/win32sck.c	2004-07-28 20:34:48.000000000 +0300
+++ perl-5.8.1/win32/win32sck.c	2004-07-28 20:39:34.000000000 +0300
@@ -16,6 +16,8 @@
 #define Win32_Winsock
 #endif
 #include <windows.h>
+#include <ws2spi.h>
+
 #include "EXTERN.h"
 #include "perl.h"
 
@@ -99,22 +101,6 @@
 void
 set_socktype(void)
 {
-#ifdef USE_SOCKETS_AS_HANDLES
-#if defined(USE_5005THREADS) || defined(USE_ITHREADS)
-    dTHX;
-    if (!w32_init_socktype) {
-#endif
-	int iSockOpt = SO_SYNCHRONOUS_NONALERT;
-	/*
-	 * Enable the use of sockets as filehandles
-	 */
-	setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
-		    (char *)&iSockOpt, sizeof(iSockOpt));
-#if defined(USE_5005THREADS) || defined(USE_ITHREADS)
-	w32_init_socktype = 1;
-    }
-#endif
-#endif	/* USE_SOCKETS_AS_HANDLES */
 }
 
 
@@ -399,6 +385,63 @@
     return r;
 }
 
+#ifdef USE_SOCKETS_AS_HANDLES
+#define WIN32_OPEN_SOCKET(af, type, protocol) open_ifs_socket(af, type, protocol)
+
+void
+convert_proto_info_w2a(WSAPROTOCOL_INFOW *in, WSAPROTOCOL_INFOA *out)
+{
+    memcpy(out, in, sizeof(WSAPROTOCOL_INFOA));
+    wcstombs(out->szProtocol, in->szProtocol, sizeof(out->szProtocol));
+}
+
+SOCKET
+open_ifs_socket(int af, int type, int protocol)
+{
+    unsigned long proto_buffers_len = 0;
+    int error_code;
+    SOCKET out = INVALID_SOCKET;
+
+    if (WSCEnumProtocols(NULL, NULL, &proto_buffers_len, &error_code) == SOCKET_ERROR
+        && error_code == WSAENOBUFS)
+    {
+        WSAPROTOCOL_INFOW *proto_buffers = (WSAPROTOCOL_INFOW *) malloc(proto_buffers_len);
+        int protocols_available = 0;       
+ 
+        if ((protocols_available = WSCEnumProtocols(NULL, proto_buffers, 
+            &proto_buffers_len, &error_code)) != SOCKET_ERROR)
+        {
+            int i;
+            for (i = 0; i < protocols_available; i++)
+            {
+                WSAPROTOCOL_INFOA proto_info;
+
+                if ((af != AF_UNSPEC && af != proto_buffers[i].iAddressFamily)
+                    || (type != proto_buffers[i].iSocketType)
+                    || (protocol != 0 && protocol != proto_buffers[i].iProtocol))
+                    continue;
+
+                if ((proto_buffers[i].dwServiceFlags1 & XP1_IFS_HANDLES) == 0)
+                    continue;
+
+                convert_proto_info_w2a(&(proto_buffers[i]), &proto_info);
+
+                out = WSASocket(af, type, protocol, &proto_info, 0, 0);
+                break;
+            }
+        }
+
+        if (proto_buffers)
+            free(proto_buffers);
+    }
+
+    return out;
+}
+
+#else
+#define WIN32_OPEN_SOCKET(af, type, protocol) socket(af, type, protocol)
+#endif
+
 SOCKET
 win32_socket(int af, int type, int protocol)
 {
@@ -408,7 +451,8 @@
     SOCKET_TEST(s = socket(af, type, protocol), INVALID_SOCKET);
 #else
     StartSockets();
-    if((s = socket(af, type, protocol)) == INVALID_SOCKET)
+
+    if((s = WIN32_OPEN_SOCKET(af, type, protocol)) == INVALID_SOCKET)
 	errno = WSAGetLastError();
     else
 	s = OPEN_SOCKET(s);

@p5pRT
Copy link
Author

p5pRT commented Jul 31, 2004

From artiom@phreaker.net

Some more fixes to the patch, suggested by Steve Hay
<steve.hay@​uk.radan.com>​:
- using New/Copy/SafeFree instead of malloc/memmove/free
- moved ws2spi.h header to win32/include/sys/socket.h
- changed linker settings in makefile.mk to use ws2_32(.lib,.dll)
instead of wsock32

Also slightly updated README.win32 (included Winsock2 requirement) and
changed WSAStartup call to pass version number of 2, not 1.1.

@p5pRT
Copy link
Author

p5pRT commented Jul 31, 2004

From artiom@phreaker.net

perl-5.8.1.patch
diff -rdu perl-5.8.1-old/README.win32 perl-5.8.1/README.win32
--- perl-5.8.1-old/README.win32	2004-07-28 20:34:42.000000000 +0300
+++ perl-5.8.1/README.win32	2004-07-31 15:27:40.000000000 +0300
@@ -745,6 +745,12 @@
 
 Most C<socket()> related calls are supported, but they may not
 behave as on Unix platforms.  See L<perlport> for the full list.
+Perl requires Winsock2 to be installed on the system. If you're
+running Win95, you can download Winsock upgrade from here:
+
+http://www.microsoft.com/windows95/downloads/contents/WUAdminTools/S_WUNetworkingTools/W95Sockets2/Default.asp
+
+Later OS versions already include Winsock2 support.
 
 Signal handling may not behave as on Unix platforms (where it
 doesn't exactly "behave", either :).  For instance, calling C<die()>
diff -rdu perl-5.8.1-old/win32/Makefile perl-5.8.1/win32/Makefile
--- perl-5.8.1-old/win32/Makefile	2004-07-28 20:34:46.000000000 +0300
+++ perl-5.8.1/win32/Makefile	2004-07-31 13:36:04.000000000 +0300
@@ -326,7 +326,7 @@
 
 # VC 6.0 can load the socket dll on demand.  Makes the test suite
 # run in about 10% less time.
-DELAYLOAD	= -DELAYLOAD:wsock32.dll -DELAYLOAD:shell32.dll delayimp.lib
+DELAYLOAD	= -DELAYLOAD:ws2_32.dll -DELAYLOAD:shell32.dll delayimp.lib
 !ENDIF
 
 ARCHDIR		= ..\lib\$(ARCHNAME)
@@ -408,7 +408,7 @@
 LIBBASEFILES	= $(CRYPT_LIB) \
 		oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib \
 		comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \
-		netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib \
+		netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib \
 		version.lib
 
 # win64 doesn't have some libs
diff -rdu perl-5.8.1-old/win32/include/sys/socket.h perl-5.8.1/win32/include/sys/socket.h
--- perl-5.8.1-old/win32/include/sys/socket.h	2004-07-28 20:34:46.000000000 +0300
+++ perl-5.8.1/win32/include/sys/socket.h	2004-07-31 14:27:02.000000000 +0300
@@ -15,7 +15,7 @@
 #  define Win32_Winsock
 #endif
 #include <windows.h>
-#include <winsock.h>
+#include <ws2spi.h>
 
 #include "win32.h"
 
diff -rdu perl-5.8.1-old/win32/makefile.mk perl-5.8.1/win32/makefile.mk
--- perl-5.8.1-old/win32/makefile.mk	2004-07-28 20:34:46.000000000 +0300
+++ perl-5.8.1/win32/makefile.mk	2004-07-31 13:42:26.000000000 +0300
@@ -312,7 +312,7 @@
 
 # VC 6.0 can load the socket dll on demand.  Makes the test suite
 # run in about 10% less time.
-DELAYLOAD	*= -DELAYLOAD:wsock32.dll -DELAYLOAD:shell32.dll delayimp.lib
+DELAYLOAD	*= -DELAYLOAD:ws2_32.dll -DELAYLOAD:shell32.dll delayimp.lib
 
 .IF "$(CFG)" == "Debug"
 .ELSE
@@ -425,7 +425,7 @@
 LIBFILES	= $(CRYPT_LIB) $(LIBC) \
 		  -lmoldname -lkernel32 -luser32 -lgdi32 \
 		  -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 \
-		  -loleaut32 -lnetapi32 -luuid -lwsock32 -lmpr \
+		  -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr \
 		  -lwinmm -lversion -lodbc32
 
 .IF  "$(CFG)" == "Debug"
@@ -505,7 +505,7 @@
 LIBBASEFILES	= $(CRYPT_LIB) \
 		oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib \
 		comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \
-		netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib \
+		netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib \
 		version.lib
 
 # win64 doesn't have some libs
diff -rdu perl-5.8.1-old/win32/win32.c perl-5.8.1/win32/win32.c
--- perl-5.8.1-old/win32/win32.c	2004-07-28 20:34:48.000000000 +0300
+++ perl-5.8.1/win32/win32.c	2004-07-31 13:36:04.000000000 +0300
@@ -5033,7 +5033,6 @@
     New(1313, w32_pseudo_children, 1, child_tab);
     w32_num_pseudo_children	= 0;
 #  endif
-    w32_init_socktype		= 0;
     w32_timerid                 = 0;
     w32_poll_count              = 0;
     for (i=0; i < SIG_SIZE; i++) {
@@ -5087,7 +5086,6 @@
     Newz(1313, dst->children, 1, child_tab);
     dst->pseudo_id		= 0;
     Newz(1313, dst->pseudo_children, 1, child_tab);
-    dst->thr_intern.Winit_socktype = 0;
     dst->timerid                 = 0;
     dst->poll_count              = 0;
     Copy(src->sigtable,dst->sigtable,SIG_SIZE,Sighandler_t);
diff -rdu perl-5.8.1-old/win32/win32.h perl-5.8.1/win32/win32.h
--- perl-5.8.1-old/win32/win32.h	2004-07-28 20:34:48.000000000 +0300
+++ perl-5.8.1/win32/win32.h	2004-07-31 13:36:04.000000000 +0300
@@ -358,9 +358,6 @@
     char		Wstrerror_buffer[512];
     struct servent	Wservent;
     char		Wgetlogin_buffer[128];
-#    ifdef USE_SOCKETS_AS_HANDLES
-    int			Winit_socktype;
-#    endif
 #    ifdef HAVE_DES_FCRYPT
     char		Wcrypt_buffer[30];
 #    endif
@@ -436,7 +433,6 @@
 #  define w32_getlogin_buffer	(thr->i.Wgetlogin_buffer)
 #  define w32_crypt_buffer	(thr->i.Wcrypt_buffer)
 #  define w32_servent		(thr->i.Wservent)
-#  define w32_init_socktype	(thr->i.Winit_socktype)
 #  define w32_use_showwindow	(thr->i.Wuse_showwindow)
 #  define w32_showwindow	(thr->i.Wshowwindow)
 #else
@@ -444,7 +440,6 @@
 #  define w32_getlogin_buffer	(PL_sys_intern.thr_intern.Wgetlogin_buffer)
 #  define w32_crypt_buffer	(PL_sys_intern.thr_intern.Wcrypt_buffer)
 #  define w32_servent		(PL_sys_intern.thr_intern.Wservent)
-#  define w32_init_socktype	(PL_sys_intern.thr_intern.Winit_socktype)
 #  define w32_use_showwindow	(PL_sys_intern.thr_intern.Wuse_showwindow)
 #  define w32_showwindow	(PL_sys_intern.thr_intern.Wshowwindow)
 #endif /* USE_5005THREADS */
diff -rdu perl-5.8.1-old/win32/win32sck.c perl-5.8.1/win32/win32sck.c
--- perl-5.8.1-old/win32/win32sck.c	2004-07-28 20:34:48.000000000 +0300
+++ perl-5.8.1/win32/win32sck.c	2004-07-31 14:21:44.000000000 +0300
@@ -16,6 +16,7 @@
 #define Win32_Winsock
 #endif
 #include <windows.h>
+
 #include "EXTERN.h"
 #include "perl.h"
 
@@ -86,11 +87,11 @@
      * initalize the winsock interface and insure that it is
      * cleaned up at exit.
      */
-    version = 0x101;
+    version = 0x2;
     if(ret = WSAStartup(version, &retdata))
 	Perl_croak_nocontext("Unable to locate winsock library!\n");
     if(retdata.wVersion != version)
-	Perl_croak_nocontext("Could not find version 1.1 of winsock dll\n");
+	Perl_croak_nocontext("Could not find version 2.0 of winsock dll\n");
 
     /* atexit((void (*)(void)) EndSockets); */
     wsock_started = 1;
@@ -99,22 +100,6 @@
 void
 set_socktype(void)
 {
-#ifdef USE_SOCKETS_AS_HANDLES
-#if defined(USE_5005THREADS) || defined(USE_ITHREADS)
-    dTHX;
-    if (!w32_init_socktype) {
-#endif
-	int iSockOpt = SO_SYNCHRONOUS_NONALERT;
-	/*
-	 * Enable the use of sockets as filehandles
-	 */
-	setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
-		    (char *)&iSockOpt, sizeof(iSockOpt));
-#if defined(USE_5005THREADS) || defined(USE_ITHREADS)
-	w32_init_socktype = 1;
-    }
-#endif
-#endif	/* USE_SOCKETS_AS_HANDLES */
 }
 
 
@@ -399,6 +384,65 @@
     return r;
 }
 
+#ifdef USE_SOCKETS_AS_HANDLES
+#define WIN32_OPEN_SOCKET(af, type, protocol) open_ifs_socket(af, type, protocol)
+
+void
+convert_proto_info_w2a(WSAPROTOCOL_INFOW *in, WSAPROTOCOL_INFOA *out)
+{
+    Copy(in, out, 1, WSAPROTOCOL_INFOA);
+    wcstombs(out->szProtocol, in->szProtocol, sizeof(out->szProtocol));
+}
+
+SOCKET
+open_ifs_socket(int af, int type, int protocol)
+{
+    unsigned long proto_buffers_len = 0;
+    int error_code;
+    SOCKET out = INVALID_SOCKET;
+
+    if (WSCEnumProtocols(NULL, NULL, &proto_buffers_len, &error_code) == SOCKET_ERROR
+        && error_code == WSAENOBUFS)
+    {
+	WSAPROTOCOL_INFOW *proto_buffers;
+        int protocols_available = 0;       
+ 
+        New(1, proto_buffers, proto_buffers_len / sizeof(WSAPROTOCOL_INFOW),
+            WSAPROTOCOL_INFOW);
+
+        if ((protocols_available = WSCEnumProtocols(NULL, proto_buffers, 
+            &proto_buffers_len, &error_code)) != SOCKET_ERROR)
+        {
+            int i;
+            for (i = 0; i < protocols_available; i++)
+            {
+                WSAPROTOCOL_INFOA proto_info;
+
+                if ((af != AF_UNSPEC && af != proto_buffers[i].iAddressFamily)
+                    || (type != proto_buffers[i].iSocketType)
+                    || (protocol != 0 && protocol != proto_buffers[i].iProtocol))
+                    continue;
+
+                if ((proto_buffers[i].dwServiceFlags1 & XP1_IFS_HANDLES) == 0)
+                    continue;
+
+                convert_proto_info_w2a(&(proto_buffers[i]), &proto_info);
+
+                out = WSASocket(af, type, protocol, &proto_info, 0, 0);
+                break;
+            }
+        }
+
+        Safefree(proto_buffers);
+    }
+
+    return out;
+}
+
+#else
+#define WIN32_OPEN_SOCKET(af, type, protocol) socket(af, type, protocol)
+#endif
+
 SOCKET
 win32_socket(int af, int type, int protocol)
 {
@@ -408,7 +452,8 @@
     SOCKET_TEST(s = socket(af, type, protocol), INVALID_SOCKET);
 #else
     StartSockets();
-    if((s = socket(af, type, protocol)) == INVALID_SOCKET)
+
+    if((s = WIN32_OPEN_SOCKET(af, type, protocol)) == INVALID_SOCKET)
 	errno = WSAGetLastError();
     else
 	s = OPEN_SOCKET(s);

@p5pRT
Copy link
Author

p5pRT commented Jul 31, 2004

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Aug 3, 2004

From artiom@phreaker.net

One more revision for patch. Moved ws2spi.h header back to win32sck.c.

Per Steve Hay's suggestion, two patches are available now​:
- perl-5.8.1-stable.patch - preserving unused Winit_socktype member from
thread_inter for the sake of binary compatibility
- perl-5.8.1-blead.patch - removing that member

@p5pRT
Copy link
Author

p5pRT commented Aug 3, 2004

From artiom@phreaker.net

perl-5.8.1-blead.patch
diff -rdu perl-5.8.1-old/README.win32 perl-5.8.1/README.win32
--- perl-5.8.1-old/README.win32	2004-07-28 20:34:42.000000000 +0300
+++ perl-5.8.1/README.win32	2004-07-31 15:27:40.000000000 +0300
@@ -745,6 +745,12 @@
 
 Most C<socket()> related calls are supported, but they may not
 behave as on Unix platforms.  See L<perlport> for the full list.
+Perl requires Winsock2 to be installed on the system. If you're
+running Win95, you can download Winsock upgrade from here:
+
+http://www.microsoft.com/windows95/downloads/contents/WUAdminTools/S_WUNetworkingTools/W95Sockets2/Default.asp
+
+Later OS versions already include Winsock2 support.
 
 Signal handling may not behave as on Unix platforms (where it
 doesn't exactly "behave", either :).  For instance, calling C<die()>
diff -rdu perl-5.8.1-old/win32/Makefile perl-5.8.1/win32/Makefile
--- perl-5.8.1-old/win32/Makefile	2004-07-28 20:34:46.000000000 +0300
+++ perl-5.8.1/win32/Makefile	2004-07-31 13:36:04.000000000 +0300
@@ -326,7 +326,7 @@
 
 # VC 6.0 can load the socket dll on demand.  Makes the test suite
 # run in about 10% less time.
-DELAYLOAD	= -DELAYLOAD:wsock32.dll -DELAYLOAD:shell32.dll delayimp.lib
+DELAYLOAD	= -DELAYLOAD:ws2_32.dll -DELAYLOAD:shell32.dll delayimp.lib
 !ENDIF
 
 ARCHDIR		= ..\lib\$(ARCHNAME)
@@ -408,7 +408,7 @@
 LIBBASEFILES	= $(CRYPT_LIB) \
 		oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib \
 		comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \
-		netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib \
+		netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib \
 		version.lib
 
 # win64 doesn't have some libs
diff -rdu perl-5.8.1-old/win32/makefile.mk perl-5.8.1/win32/makefile.mk
--- perl-5.8.1-old/win32/makefile.mk	2004-07-28 20:34:46.000000000 +0300
+++ perl-5.8.1/win32/makefile.mk	2004-07-31 13:42:26.000000000 +0300
@@ -312,7 +312,7 @@
 
 # VC 6.0 can load the socket dll on demand.  Makes the test suite
 # run in about 10% less time.
-DELAYLOAD	*= -DELAYLOAD:wsock32.dll -DELAYLOAD:shell32.dll delayimp.lib
+DELAYLOAD	*= -DELAYLOAD:ws2_32.dll -DELAYLOAD:shell32.dll delayimp.lib
 
 .IF "$(CFG)" == "Debug"
 .ELSE
@@ -425,7 +425,7 @@
 LIBFILES	= $(CRYPT_LIB) $(LIBC) \
 		  -lmoldname -lkernel32 -luser32 -lgdi32 \
 		  -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 \
-		  -loleaut32 -lnetapi32 -luuid -lwsock32 -lmpr \
+		  -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr \
 		  -lwinmm -lversion -lodbc32
 
 .IF  "$(CFG)" == "Debug"
@@ -505,7 +505,7 @@
 LIBBASEFILES	= $(CRYPT_LIB) \
 		oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib \
 		comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \
-		netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib \
+		netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib \
 		version.lib
 
 # win64 doesn't have some libs
diff -rdu perl-5.8.1-old/win32/win32.c perl-5.8.1/win32/win32.c
--- perl-5.8.1-old/win32/win32.c	2004-07-28 20:34:48.000000000 +0300
+++ perl-5.8.1/win32/win32.c	2004-07-31 13:36:04.000000000 +0300
@@ -5033,7 +5033,6 @@
     New(1313, w32_pseudo_children, 1, child_tab);
     w32_num_pseudo_children	= 0;
 #  endif
-    w32_init_socktype		= 0;
     w32_timerid                 = 0;
     w32_poll_count              = 0;
     for (i=0; i < SIG_SIZE; i++) {
@@ -5087,7 +5086,6 @@
     Newz(1313, dst->children, 1, child_tab);
     dst->pseudo_id		= 0;
     Newz(1313, dst->pseudo_children, 1, child_tab);
-    dst->thr_intern.Winit_socktype = 0;
     dst->timerid                 = 0;
     dst->poll_count              = 0;
     Copy(src->sigtable,dst->sigtable,SIG_SIZE,Sighandler_t);
diff -rdu perl-5.8.1-old/win32/win32.h perl-5.8.1/win32/win32.h
--- perl-5.8.1-old/win32/win32.h	2004-07-28 20:34:48.000000000 +0300
+++ perl-5.8.1/win32/win32.h	2004-07-31 13:36:04.000000000 +0300
@@ -358,9 +358,6 @@
     char		Wstrerror_buffer[512];
     struct servent	Wservent;
     char		Wgetlogin_buffer[128];
-#    ifdef USE_SOCKETS_AS_HANDLES
-    int			Winit_socktype;
-#    endif
 #    ifdef HAVE_DES_FCRYPT
     char		Wcrypt_buffer[30];
 #    endif
@@ -436,7 +433,6 @@
 #  define w32_getlogin_buffer	(thr->i.Wgetlogin_buffer)
 #  define w32_crypt_buffer	(thr->i.Wcrypt_buffer)
 #  define w32_servent		(thr->i.Wservent)
-#  define w32_init_socktype	(thr->i.Winit_socktype)
 #  define w32_use_showwindow	(thr->i.Wuse_showwindow)
 #  define w32_showwindow	(thr->i.Wshowwindow)
 #else
@@ -444,7 +440,6 @@
 #  define w32_getlogin_buffer	(PL_sys_intern.thr_intern.Wgetlogin_buffer)
 #  define w32_crypt_buffer	(PL_sys_intern.thr_intern.Wcrypt_buffer)
 #  define w32_servent		(PL_sys_intern.thr_intern.Wservent)
-#  define w32_init_socktype	(PL_sys_intern.thr_intern.Winit_socktype)
 #  define w32_use_showwindow	(PL_sys_intern.thr_intern.Wuse_showwindow)
 #  define w32_showwindow	(PL_sys_intern.thr_intern.Wshowwindow)
 #endif /* USE_5005THREADS */
diff -rdu perl-5.8.1-old/win32/win32sck.c perl-5.8.1/win32/win32sck.c
--- perl-5.8.1-old/win32/win32sck.c	2004-07-28 20:34:48.000000000 +0300
+++ perl-5.8.1/win32/win32sck.c	2004-08-03 19:13:56.000000000 +0300
@@ -16,6 +16,8 @@
 #define Win32_Winsock
 #endif
 #include <windows.h>
+#include <ws2spi.h>
+
 #include "EXTERN.h"
 #include "perl.h"
 
@@ -86,11 +88,11 @@
      * initalize the winsock interface and insure that it is
      * cleaned up at exit.
      */
-    version = 0x101;
+    version = 0x2;
     if(ret = WSAStartup(version, &retdata))
 	Perl_croak_nocontext("Unable to locate winsock library!\n");
     if(retdata.wVersion != version)
-	Perl_croak_nocontext("Could not find version 1.1 of winsock dll\n");
+	Perl_croak_nocontext("Could not find version 2.0 of winsock dll\n");
 
     /* atexit((void (*)(void)) EndSockets); */
     wsock_started = 1;
@@ -99,22 +101,6 @@
 void
 set_socktype(void)
 {
-#ifdef USE_SOCKETS_AS_HANDLES
-#if defined(USE_5005THREADS) || defined(USE_ITHREADS)
-    dTHX;
-    if (!w32_init_socktype) {
-#endif
-	int iSockOpt = SO_SYNCHRONOUS_NONALERT;
-	/*
-	 * Enable the use of sockets as filehandles
-	 */
-	setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
-		    (char *)&iSockOpt, sizeof(iSockOpt));
-#if defined(USE_5005THREADS) || defined(USE_ITHREADS)
-	w32_init_socktype = 1;
-    }
-#endif
-#endif	/* USE_SOCKETS_AS_HANDLES */
 }
 
 
@@ -399,6 +385,65 @@
     return r;
 }
 
+#ifdef USE_SOCKETS_AS_HANDLES
+#define WIN32_OPEN_SOCKET(af, type, protocol) open_ifs_socket(af, type, protocol)
+
+void
+convert_proto_info_w2a(WSAPROTOCOL_INFOW *in, WSAPROTOCOL_INFOA *out)
+{
+    Copy(in, out, 1, WSAPROTOCOL_INFOA);
+    wcstombs(out->szProtocol, in->szProtocol, sizeof(out->szProtocol));
+}
+
+SOCKET
+open_ifs_socket(int af, int type, int protocol)
+{
+    unsigned long proto_buffers_len = 0;
+    int error_code;
+    SOCKET out = INVALID_SOCKET;
+
+    if (WSCEnumProtocols(NULL, NULL, &proto_buffers_len, &error_code) == SOCKET_ERROR
+        && error_code == WSAENOBUFS)
+    {
+	WSAPROTOCOL_INFOW *proto_buffers;
+        int protocols_available = 0;       
+ 
+        New(1, proto_buffers, proto_buffers_len / sizeof(WSAPROTOCOL_INFOW),
+            WSAPROTOCOL_INFOW);
+
+        if ((protocols_available = WSCEnumProtocols(NULL, proto_buffers, 
+            &proto_buffers_len, &error_code)) != SOCKET_ERROR)
+        {
+            int i;
+            for (i = 0; i < protocols_available; i++)
+            {
+                WSAPROTOCOL_INFOA proto_info;
+
+                if ((af != AF_UNSPEC && af != proto_buffers[i].iAddressFamily)
+                    || (type != proto_buffers[i].iSocketType)
+                    || (protocol != 0 && protocol != proto_buffers[i].iProtocol))
+                    continue;
+
+                if ((proto_buffers[i].dwServiceFlags1 & XP1_IFS_HANDLES) == 0)
+                    continue;
+
+                convert_proto_info_w2a(&(proto_buffers[i]), &proto_info);
+
+                out = WSASocket(af, type, protocol, &proto_info, 0, 0);
+                break;
+            }
+        }
+
+        Safefree(proto_buffers);
+    }
+
+    return out;
+}
+
+#else
+#define WIN32_OPEN_SOCKET(af, type, protocol) socket(af, type, protocol)
+#endif
+
 SOCKET
 win32_socket(int af, int type, int protocol)
 {
@@ -408,7 +453,8 @@
     SOCKET_TEST(s = socket(af, type, protocol), INVALID_SOCKET);
 #else
     StartSockets();
-    if((s = socket(af, type, protocol)) == INVALID_SOCKET)
+
+    if((s = WIN32_OPEN_SOCKET(af, type, protocol)) == INVALID_SOCKET)
 	errno = WSAGetLastError();
     else
 	s = OPEN_SOCKET(s);

@p5pRT
Copy link
Author

p5pRT commented Aug 3, 2004

From artiom@phreaker.net

perl-5.8.1-stable.patch
diff -rdu perl-5.8.1-old/README.win32 perl-5.8.1/README.win32
--- perl-5.8.1-old/README.win32	2004-07-28 20:34:42.000000000 +0300
+++ perl-5.8.1/README.win32	2004-07-31 15:27:40.000000000 +0300
@@ -745,6 +745,12 @@
 
 Most C<socket()> related calls are supported, but they may not
 behave as on Unix platforms.  See L<perlport> for the full list.
+Perl requires Winsock2 to be installed on the system. If you're
+running Win95, you can download Winsock upgrade from here:
+
+http://www.microsoft.com/windows95/downloads/contents/WUAdminTools/S_WUNetworkingTools/W95Sockets2/Default.asp
+
+Later OS versions already include Winsock2 support.
 
 Signal handling may not behave as on Unix platforms (where it
 doesn't exactly "behave", either :).  For instance, calling C<die()>
diff -rdu perl-5.8.1-old/win32/Makefile perl-5.8.1/win32/Makefile
--- perl-5.8.1-old/win32/Makefile	2004-07-28 20:34:46.000000000 +0300
+++ perl-5.8.1/win32/Makefile	2004-07-31 13:36:04.000000000 +0300
@@ -326,7 +326,7 @@
 
 # VC 6.0 can load the socket dll on demand.  Makes the test suite
 # run in about 10% less time.
-DELAYLOAD	= -DELAYLOAD:wsock32.dll -DELAYLOAD:shell32.dll delayimp.lib
+DELAYLOAD	= -DELAYLOAD:ws2_32.dll -DELAYLOAD:shell32.dll delayimp.lib
 !ENDIF
 
 ARCHDIR		= ..\lib\$(ARCHNAME)
@@ -408,7 +408,7 @@
 LIBBASEFILES	= $(CRYPT_LIB) \
 		oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib \
 		comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \
-		netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib \
+		netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib \
 		version.lib
 
 # win64 doesn't have some libs
diff -rdu perl-5.8.1-old/win32/makefile.mk perl-5.8.1/win32/makefile.mk
--- perl-5.8.1-old/win32/makefile.mk	2004-07-28 20:34:46.000000000 +0300
+++ perl-5.8.1/win32/makefile.mk	2004-07-31 13:42:26.000000000 +0300
@@ -312,7 +312,7 @@
 
 # VC 6.0 can load the socket dll on demand.  Makes the test suite
 # run in about 10% less time.
-DELAYLOAD	*= -DELAYLOAD:wsock32.dll -DELAYLOAD:shell32.dll delayimp.lib
+DELAYLOAD	*= -DELAYLOAD:ws2_32.dll -DELAYLOAD:shell32.dll delayimp.lib
 
 .IF "$(CFG)" == "Debug"
 .ELSE
@@ -425,7 +425,7 @@
 LIBFILES	= $(CRYPT_LIB) $(LIBC) \
 		  -lmoldname -lkernel32 -luser32 -lgdi32 \
 		  -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 \
-		  -loleaut32 -lnetapi32 -luuid -lwsock32 -lmpr \
+		  -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr \
 		  -lwinmm -lversion -lodbc32
 
 .IF  "$(CFG)" == "Debug"
@@ -505,7 +505,7 @@
 LIBBASEFILES	= $(CRYPT_LIB) \
 		oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib \
 		comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \
-		netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib \
+		netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib \
 		version.lib
 
 # win64 doesn't have some libs
diff -rdu perl-5.8.1-old/win32/win32sck.c perl-5.8.1/win32/win32sck.c
--- perl-5.8.1-old/win32/win32sck.c	2004-07-28 20:34:48.000000000 +0300
+++ perl-5.8.1/win32/win32sck.c	2004-08-03 19:17:30.000000000 +0300
@@ -16,6 +16,8 @@
 #define Win32_Winsock
 #endif
 #include <windows.h>
+#include <ws2spi.h>
+
 #include "EXTERN.h"
 #include "perl.h"
 
@@ -86,11 +88,11 @@
      * initalize the winsock interface and insure that it is
      * cleaned up at exit.
      */
-    version = 0x101;
+    version = 0x2;
     if(ret = WSAStartup(version, &retdata))
 	Perl_croak_nocontext("Unable to locate winsock library!\n");
     if(retdata.wVersion != version)
-	Perl_croak_nocontext("Could not find version 1.1 of winsock dll\n");
+	Perl_croak_nocontext("Could not find version 2.0 of winsock dll\n");
 
     /* atexit((void (*)(void)) EndSockets); */
     wsock_started = 1;
@@ -103,14 +105,6 @@
 #if defined(USE_5005THREADS) || defined(USE_ITHREADS)
     dTHX;
     if (!w32_init_socktype) {
-#endif
-	int iSockOpt = SO_SYNCHRONOUS_NONALERT;
-	/*
-	 * Enable the use of sockets as filehandles
-	 */
-	setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
-		    (char *)&iSockOpt, sizeof(iSockOpt));
-#if defined(USE_5005THREADS) || defined(USE_ITHREADS)
 	w32_init_socktype = 1;
     }
 #endif
@@ -399,6 +393,65 @@
     return r;
 }
 
+#ifdef USE_SOCKETS_AS_HANDLES
+#define WIN32_OPEN_SOCKET(af, type, protocol) open_ifs_socket(af, type, protocol)
+
+void
+convert_proto_info_w2a(WSAPROTOCOL_INFOW *in, WSAPROTOCOL_INFOA *out)
+{
+    Copy(in, out, 1, WSAPROTOCOL_INFOA);
+    wcstombs(out->szProtocol, in->szProtocol, sizeof(out->szProtocol));
+}
+
+SOCKET
+open_ifs_socket(int af, int type, int protocol)
+{
+    unsigned long proto_buffers_len = 0;
+    int error_code;
+    SOCKET out = INVALID_SOCKET;
+
+    if (WSCEnumProtocols(NULL, NULL, &proto_buffers_len, &error_code) == SOCKET_ERROR
+        && error_code == WSAENOBUFS)
+    {
+	WSAPROTOCOL_INFOW *proto_buffers;
+        int protocols_available = 0;       
+ 
+        New(1, proto_buffers, proto_buffers_len / sizeof(WSAPROTOCOL_INFOW),
+            WSAPROTOCOL_INFOW);
+
+        if ((protocols_available = WSCEnumProtocols(NULL, proto_buffers, 
+            &proto_buffers_len, &error_code)) != SOCKET_ERROR)
+        {
+            int i;
+            for (i = 0; i < protocols_available; i++)
+            {
+                WSAPROTOCOL_INFOA proto_info;
+
+                if ((af != AF_UNSPEC && af != proto_buffers[i].iAddressFamily)
+                    || (type != proto_buffers[i].iSocketType)
+                    || (protocol != 0 && protocol != proto_buffers[i].iProtocol))
+                    continue;
+
+                if ((proto_buffers[i].dwServiceFlags1 & XP1_IFS_HANDLES) == 0)
+                    continue;
+
+                convert_proto_info_w2a(&(proto_buffers[i]), &proto_info);
+
+                out = WSASocket(af, type, protocol, &proto_info, 0, 0);
+                break;
+            }
+        }
+
+        Safefree(proto_buffers);
+    }
+
+    return out;
+}
+
+#else
+#define WIN32_OPEN_SOCKET(af, type, protocol) socket(af, type, protocol)
+#endif
+
 SOCKET
 win32_socket(int af, int type, int protocol)
 {
@@ -408,7 +461,8 @@
     SOCKET_TEST(s = socket(af, type, protocol), INVALID_SOCKET);
 #else
     StartSockets();
-    if((s = socket(af, type, protocol)) == INVALID_SOCKET)
+
+    if((s = WIN32_OPEN_SOCKET(af, type, protocol)) == INVALID_SOCKET)
 	errno = WSAGetLastError();
     else
 	s = OPEN_SOCKET(s);

@p5pRT
Copy link
Author

p5pRT commented Aug 6, 2004

From @steve-m-hay

Fixed by change #23200.

@p5pRT
Copy link
Author

p5pRT commented Aug 6, 2004

@steve-m-hay - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant