PERL PERL5 CHANGES 30 CHANGE 23317 INTEGRATE
Date: Fri, 10 Sep 2004 08:00:00 -0700

Subject: Change 23317: Integrate:
From: nick@no-spam (Nicholas Clark)

Change 23317 by nicholas@no-spam on 2004/09/10 14:37:25

Integrate:
[ 23200]
Fix [perl #24269] socket() call uses non-IFS providers causing subsequent print/read to hang or misbehave
Patch supplied by Artiom Morozov <artiom@no-spam>
in the bug report at http://rt.perl.org/rt3/index.html?q=24269

(strictly actually use the alternative supplied "stable" patch)

[ 23275]
Implement new environment variable to allow the use of non-IFS compatible LSP's on Windows to allow Perl to work in conjunction with a firewall such as McAfee Guardian.

Bug report and possible solutions by Ken Fox <kfox@no-spam>;
further assistance by Artiom Morozov <artiom@no-spam>.

Affected files ...

... //depot/maint-5.8/perl/README.win32#11 integrate ... //depot/maint-5.8/perl/pod/perlrun.pod#42 integrate ... //depot/maint-5.8/perl/win32/Makefile#36 integrate ... //depot/maint-5.8/perl/win32/makefile.mk#43 integrate ... //depot/maint-5.8/perl/win32/win32sck.c#4 edit
Differences ...

==== //depot/maint-5.8/perl/README.win32#11 (text) ====
Index: perl/README.win32
--- perl/README.win32#10~23314~ Fri Sep 10 03:24:09 2004
+++ perl/README.win32 Fri Sep 10 07:37:25 2004
@@no-spam -834,6 +834,12 @@no-spam 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()>

==== //depot/maint-5.8/perl/pod/perlrun.pod#42 (text) ====
Index: perl/pod/perlrun.pod --- perl/pod/perlrun.pod#41~23314~ Fri Sep 10 03:24:09 2004
+++ perl/pod/perlrun.pod Fri Sep 10 07:37:25 2004
@@no-spam -1101,6 +1101,20 @@no-spam interfere with the proper functioning of other programs (which usually look in COMSPEC to find a shell fit for interactive use).
+=item PERL_ALLOW_NON_IFS_LSP (specific to the Win32 port)
+
+Set to 1 to allow the use of non-IFS compatible LSP's.
+Perl normally searches for an IFS-compatible LSP because this is required +for its emulation of Windows sockets as real filehandles. However, this may +cause problems if you have a firewall such as McAfee Guardian which requires +all applications to use its LSP which is not IFS-compatible, because clearly +Perl will normally avoid using such an LSP.
+Setting this environment variable to 1 means that Perl will simply use the +first suitable LSP enumerated in the catalog, which keeps McAfee Guardian +happy (and in that particular case Perl still works too because McAfee +Guardian's LSP actually plays some other games which allow applications +requiring IFS compatibility to work).
+
=item PERL_DEBUG_MSTATS Relevant only if perl is compiled with the malloc included with the perl
==== //depot/maint-5.8/perl/win32/Makefile#36 (text) ====
Index: perl/win32/Makefile --- perl/win32/Makefile#35~23153~ Thu Jul 22 10:05:37 2004
+++ perl/win32/Makefile Fri Sep 10 07:37:25 2004
@@no-spam -326,7 +326,7 @@no-spam # 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)
@@no-spam -412,7 +412,7 @@no-spam 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
==== //depot/maint-5.8/perl/win32/makefile.mk#43 (text) ====
Index: perl/win32/makefile.mk --- perl/win32/makefile.mk#42~23153~ Thu Jul 22 10:05:37 2004
+++ perl/win32/makefile.mk Fri Sep 10 07:37:25 2004
@@no-spam -309,7 +309,7 @@no-spam # 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 @@no-spam -419,7 +419,7 @@no-spam 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"
@@no-spam -503,7 +503,7 @@no-spam 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
==== //depot/maint-5.8/perl/win32/win32sck.c#4 (text) ====
Index: perl/win32/win32sck.c --- perl/win32/win32sck.c#3~22324~ Tue Feb 17 14:37:52 2004
+++ perl/win32/win32sck.c Fri Sep 10 07:37:25 2004
@@no-spam -16,6 +16,8 @@no-spam #define Win32_Winsock #endif #include <windows.h>
+#include <ws2spi.h>
+
#include "EXTERN.h"
#include "perl.h"
@@no-spam -86,11 +88,11 @@no-spam * 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;
@@no-spam -103,14 +105,6 @@no-spam #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 @@no-spam -399,6 +393,70 @@no-spam 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)
+{
+ dTHX;
+ char *s;
+ unsigned long proto_buffers_len = 0;
+ int error_code;
+ SOCKET out = INVALID_SOCKET;
+
+ if ((s = PerlEnv_getenv("PERL_ALLOW_NON_IFS_LSP")) && atoi(s))
+ return WSASocket(af, type, protocol, NULL, 0, 0);
+
+ 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)
{
@@no-spam -408,7 +466,8 @@no-spam 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);
End of Patch.