diff --git a/ChangeLog b/ChangeLog index 1ce3aec79d..e82f838d8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +Wed Jun 7 10:45:10 2006 NAKAMURA Usaku + + * win32/{configure.bat, setup.mak, Makefile.sub, win32.h}: add + support new configure option `--with-winsock2'. + + * win32/win32.c (StartSockets): ditto. + + * ext/socket/extconf.rb: ditto. + + * win32/win32.c (open_ifs_socket): new function. + + * win32/win32.c (StartSockets, rb_w32_socket): use open_ifs_socket() + instead of socket(). + ifs socket support is backported from trunk. + Wed Jun 7 09:14:44 2006 Yukihiro Matsumoto * eval.c (rb_call0): binding for the return event hook should have diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb index 5ee30a2228..6469535ca3 100644 --- a/ext/socket/extconf.rb +++ b/ext/socket/extconf.rb @@ -6,7 +6,11 @@ when /bccwin32/ have_library("ws2_32", "WSACleanup") when /mswin32|mingw/ test_func = "WSACleanup" - have_library("wsock32", "WSACleanup") + if /USE_WINSOCK2/ =~ $CPPFLAGS + have_library("ws2_32", "WSACleanup") + else + have_library("wsock32", "WSACleanup") + end when /cygwin/ test_func = "socket" when /beos/ diff --git a/win32/Makefile.sub b/win32/Makefile.sub index 0e1d4fedf8..fa8e3dbfd7 100644 --- a/win32/Makefile.sub +++ b/win32/Makefile.sub @@ -130,7 +130,11 @@ RFLAGS = -r !if !defined(EXTLIBS) EXTLIBS = !endif +!if !defined(USE_WINSOCK2) LIBS = oldnames.lib user32.lib advapi32.lib wsock32.lib $(EXTLIBS) +!else +LIBS = oldnames.lib user32.lib advapi32.lib ws2_32.lib $(EXTLIBS) +!endif MISSING = acosh.obj crypt.obj erf.obj win32.obj ARFLAGS = -machine:$(MACHINE) -out: @@ -138,6 +142,9 @@ CC = $(CC) -nologo LD = $(CC) LDSHARED = $(LD) -LD XCFLAGS = -DRUBY_EXPORT -I. -I$(srcdir) -I$(srcdir)/missing +!if defined(USE_WINSOCK2) +CPPFLAGS = $(CPPFLAGS) -DUSE_WINSOCK2 +!endif !if $(MSC_VER) >= 1400 # Prevents VC++ 2005 (cl ver 14) warnings CPPFLAGS = $(CPPFLAGS) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE diff --git a/win32/configure.bat b/win32/configure.bat index 671c456144..f8fc4f686b 100755 --- a/win32/configure.bat +++ b/win32/configure.bat @@ -16,6 +16,7 @@ if "%1" == "srcdir" goto :srcdir if "%1" == "--target" goto :target if "%1" == "target" goto :target if "%1" == "--with-static-linked-ext" goto :extstatic +if "%1" == "--with-winsock2" goto :winsock2 if "%1" == "--program-suffix" goto :suffix if "%1" == "--program-name" goto :progname if "%1" == "--enable-install-doc" goto :enable-rdoc @@ -60,6 +61,10 @@ goto :loop echo>> ~tmp~.mak "EXTSTATIC=static" \ shift goto :loop +:winsock2 + echo>> ~tmp~.mak "USE_WINSOCK2=1" \ + shift +goto :loop :enable-rdoc echo>> ~tmp~.mak "RDOCTARGET=install-doc" \ shift diff --git a/win32/setup.mak b/win32/setup.mak index 1d463d1b36..da7853bb20 100644 --- a/win32/setup.mak +++ b/win32/setup.mak @@ -41,6 +41,9 @@ MAKE = nmake srcdir = $(srcdir:\=/) prefix = $(prefix:\=/) EXTSTATIC = $(EXTSTATIC) +!if defined(USE_WINSOCK2) +USE_WINSOCK2 = $(USE_WINSOCK2) +!endif !if defined(RDOCTARGET) RDOCTARGET = $(RDOCTARGET) !endif diff --git a/win32/win32.c b/win32/win32.c index 74ecebb91d..3e9846d5c8 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -1989,12 +1989,21 @@ StartSockets () WORD version; WSADATA retdata; int ret; +#ifndef USE_WINSOCK2 int iSockOpt; - +#endif + // // initalize the winsock interface and insure that it's // cleaned up at exit. // +#ifdef USE_WINSOCK2 + version = MAKEWORD(2, 0); + if (WSAStartup(version, &retdata)) + rb_fatal ("Unable to locate winsock library!\n"); + if (LOBYTE(retdata.wVersion) != 2) + rb_fatal("could not find version 2 of winsock dll\n"); +#else version = MAKEWORD(1, 1); if (ret = WSAStartup(version, &retdata)) rb_fatal ("Unable to locate winsock library!\n"); @@ -2003,23 +2012,26 @@ StartSockets () if (HIBYTE(retdata.wVersion) != 1) rb_fatal("could not find version 1 of winsock dll\n"); +#endif /* USE_WINSOCK2 */ atexit((void (*)(void)) WSACleanup); -#ifndef SO_SYNCHRONOUS_NONALERT -#define SO_SYNCHRONOUS_NONALERT 0x20 -#endif +#ifndef USE_WINSOCK2 +# ifndef SO_SYNCHRONOUS_NONALERT +# define SO_SYNCHRONOUS_NONALERT 0x20 +# endif iSockOpt = SO_SYNCHRONOUS_NONALERT; /* * Enable the use of sockets as filehandles */ -#ifndef SO_OPENTYPE -#define SO_OPENTYPE 0x7008 -#endif +# ifndef SO_OPENTYPE +# define SO_OPENTYPE 0x7008 +# endif setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&iSockOpt, sizeof(iSockOpt)); +#endif /* USE_WINSOCK2 */ main_thread.handle = GetCurrentThreadHandle(); main_thread.id = GetCurrentThreadId(); @@ -2284,7 +2296,54 @@ rb_w32_shutdown(int s, int how) return r; } +#ifdef USE_WINSOCK2 +static SOCKET +open_ifs_socket(int af, int type, int protocol) +{ + unsigned long proto_buffers_len = 0; + int error_code; + SOCKET out = INVALID_SOCKET; + + if (WSAEnumProtocols(NULL, NULL, &proto_buffers_len) == SOCKET_ERROR) { + error_code = WSAGetLastError(); + if (error_code == WSAENOBUFS) { + WSAPROTOCOL_INFO *proto_buffers; + int protocols_available = 0; + + proto_buffers = (WSAPROTOCOL_INFO *)malloc(proto_buffers_len); + + protocols_available = + WSAEnumProtocols(NULL, proto_buffers, &proto_buffers_len); + if (protocols_available != SOCKET_ERROR) { + int i; + for (i = 0; i < protocols_available; i++) { + 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; + + out = WSASocket(af, type, protocol, &(proto_buffers[i]), 0, 0); + break; + } + } + + free(proto_buffers); + } + } + + return out; +} +#endif /* USE_WINSOCK2 */ + #undef socket +#ifdef USE_WINSOCK2 +#define open_socket(a, t, p) open_ifs_socket(a, t, p) +#else +#define open_socket(a, t, p) socket(a, t, p) +#endif int rb_w32_socket(int af, int type, int protocol) @@ -2296,7 +2355,7 @@ rb_w32_socket(int af, int type, int protocol) StartSockets(); } RUBY_CRITICAL({ - s = socket(af, type, protocol); + s = open_socket(af, type, protocol); if (s == INVALID_SOCKET) { errno = map_errno(WSAGetLastError()); fd = -1; diff --git a/win32/win32.h b/win32/win32.h index 2d88de472a..713ae32c02 100644 --- a/win32/win32.h +++ b/win32/win32.h @@ -23,6 +23,9 @@ #if !defined(IN) && !defined(FLOAT) #define OpenFile WINAPI_OpenFile #ifdef __BORLANDC__ +#define USE_WINSOCK2 +#endif +#ifdef USE_WINSOCK2 #include #include #else