summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--ext/socket/extconf.rb6
-rw-r--r--win32/Makefile.sub7
-rwxr-xr-xwin32/configure.bat5
-rw-r--r--win32/setup.mak3
-rw-r--r--win32/win32.c75
-rw-r--r--win32/win32.h3
7 files changed, 105 insertions, 9 deletions
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 <usa@ruby-lang.org>
+
+ * 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 <matz@ruby-lang.org>
* 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 <winsock2.h>
#include <windows.h>
#else