summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--configure.in2
-rw-r--r--ext/socket/extconf.rb5
-rw-r--r--include/ruby/win32.h28
-rw-r--r--win32/Makefile.sub2
-rw-r--r--win32/win32.c86
6 files changed, 122 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 532ce435d4..640f3447bb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Mon May 13 20:23:24 2013 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ * win32/win32.c, include/ruby/win32.h (getipaddrs): [experimental]
+ emulate getipaddrs(3) on Unix.
+
+ * win32/Makefile.sub, configure.in (LIBS): need iphlpapi.lib for above
+ function.
+
+ * include/ruby/win32.h (socketpair): rb_w32_socketpair() doesn't
+ substitute for any function, so use non-prefixed name.
+
+ * ext/socket/extconf.rb (socketpair); follow above change.
+
Mon May 13 20:11:06 2013 Koichi Sasada <ko1@atdot.net>
* iseq.c (prepare_iseq_build): remove additional line braek.
diff --git a/configure.in b/configure.in
index 6050b15d2a..3afd4fd2c0 100644
--- a/configure.in
+++ b/configure.in
@@ -921,7 +921,7 @@ main()
AC_CHECK_FUNCS(cygwin_conv_path)
AC_LIBOBJ([langinfo])
],
-[mingw*], [ LIBS="-lshell32 -lws2_32 -limagehlp -lshlwapi $LIBS"
+[mingw*], [ LIBS="-lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi $LIBS"
ac_cv_header_a_out_h=no
ac_cv_header_pwd_h=no
ac_cv_header_utime_h=no
diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb
index f7470c06dc..a6a86b967a 100644
--- a/ext/socket/extconf.rb
+++ b/ext/socket/extconf.rb
@@ -426,11 +426,6 @@ EOF
have_func("hsterror", headers)
have_func('getipnodebyname("", 0, 0, (int *)0)', headers) # RFC 2553
have_func('gethostbyname2("", 0)', headers) # RFC 2133
- if !have_func("socketpair(0, 0, 0, 0)", headers) and
- have_func("rb_w32_socketpair(0, 0, 0, 0)", headers)
- $defs << "-Dsocketpair(a,b,c,d)=rb_w32_socketpair((a),(b),(c),(d))"
- $defs << "-DHAVE_SOCKETPAIR"
- end
unless have_func("gethostname((char *)0, 0)", headers)
have_func("uname((struct utsname *)NULL)", headers)
end
diff --git a/include/ruby/win32.h b/include/ruby/win32.h
index 8a1bf6fb8a..0392aad108 100644
--- a/include/ruby/win32.h
+++ b/include/ruby/win32.h
@@ -37,6 +37,7 @@ extern "C++" { /* template without extern "C++" */
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
+#include <iphlpapi.h>
#if defined(__cplusplus) && defined(_MSC_VER)
}
#endif
@@ -225,6 +226,26 @@ struct msghdr {
int msg_flags;
};
+/* for getifaddrs() and others */
+struct ifaddrs {
+ struct ifaddrs *ifa_next;
+ char *ifa_name;
+ u_int ifa_flags;
+ struct sockaddr *ifa_addr;
+ struct sockaddr *ifa_netmask;
+ struct sockaddr *ifa_broadaddr;
+ struct sockaddr *ifa_dstaddr;
+ void *ifa_data;
+};
+#ifdef IF_NAMESIZE
+#define IFNAMSIZ IF_NAMESIZE
+#else
+#define IFNAMSIZ 256
+#endif
+#ifdef IFF_POINTTOPOINT
+#define IFF_POINTOPOINT IFF_POINTTOPOINT
+#endif
+
extern DWORD rb_w32_osid(void);
extern int rb_w32_cmdvector(const char *, char ***);
extern rb_pid_t rb_w32_pipe_exec(const char *, const char *, int, int *, int *);
@@ -260,7 +281,9 @@ extern struct protoent *WSAAPI rb_w32_getprotobyname(const char *);
extern struct protoent *WSAAPI rb_w32_getprotobynumber(int);
extern struct servent *WSAAPI rb_w32_getservbyname(const char *, const char *);
extern struct servent *WSAAPI rb_w32_getservbyport(int, const char *);
-extern int rb_w32_socketpair(int, int, int, int *);
+extern int socketpair(int, int, int, int *);
+extern int getifaddrs(struct ifaddrs **);
+extern void freeifaddrs(struct ifaddrs *);
extern char * rb_w32_getcwd(char *, int);
extern char * rb_w32_ugetenv(const char *);
extern char * rb_w32_getenv(const char *);
@@ -658,9 +681,6 @@ extern char *rb_w32_strerror(int);
#undef getservbyport
#define getservbyport(p, pr) rb_w32_getservbyport(p, pr)
-#undef socketpair
-#define socketpair(a, t, p, s) rb_w32_socketpair(a, t, p, s)
-
#undef get_osfhandle
#define get_osfhandle(h) rb_w32_get_osfhandle(h)
diff --git a/win32/Makefile.sub b/win32/Makefile.sub
index e753045aa8..98347509aa 100644
--- a/win32/Makefile.sub
+++ b/win32/Makefile.sub
@@ -227,7 +227,7 @@ EXTLIBS =
EXTSOLIBS =
!endif
!if !defined(LIBS)
-LIBS = oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib imagehlp.lib shlwapi.lib $(EXTLIBS)
+LIBS = oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib iphlpapi.lib imagehlp.lib shlwapi.lib $(EXTLIBS)
!endif
!if !defined(MISSING)
MISSING = acosh.obj cbrt.obj crypt.obj erf.obj ffs.obj langinfo.obj lgamma_r.obj strlcat.obj strlcpy.obj tgamma.obj win32/win32.obj win32/file.obj setproctitle.obj
diff --git a/win32/win32.c b/win32/win32.c
index 6615437cb9..c960bd4a8f 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -1725,8 +1725,6 @@ rb_w32_cmdvector(const char *cmd, char ***vec)
// UNIX compatible directory access functions for NT
//
-#define PATHLEN 1024
-
//
// The idea here is to read all the directory names into a string table
// (separated by nulls) and when one of the other dir functions is called
@@ -3714,7 +3712,7 @@ socketpair_internal(int af, int type, int protocol, SOCKET *sv)
/* License: Ruby's */
int
-rb_w32_socketpair(int af, int type, int protocol, int *sv)
+socketpair(int af, int type, int protocol, int *sv)
{
SOCKET pair[2];
@@ -3738,6 +3736,88 @@ rb_w32_socketpair(int af, int type, int protocol, int *sv)
return 0;
}
+/* License: Ruby's */
+int
+getifaddrs(struct ifaddrs **ifap)
+{
+ ULONG size = 0;
+ ULONG ret;
+ IP_ADAPTER_ADDRESSES *root, *addr;
+ struct ifaddrs *prev;
+
+ ret = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size);
+ if (ret != ERROR_BUFFER_OVERFLOW) {
+ errno = map_errno(ret);
+ return -1;
+ }
+ root = ruby_xmalloc(size);
+ ret = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, root, &size);
+ if (ret != ERROR_SUCCESS) {
+ errno = map_errno(ret);
+ ruby_xfree(root);
+ return -1;
+ }
+
+ for (prev = NULL, addr = root; addr; addr = addr->Next) {
+ struct ifaddrs *ifa = ruby_xcalloc(1, sizeof(*ifa));
+ if (prev)
+ prev->ifa_next = ifa;
+ else
+ *ifap = ifa;
+
+ ifa->ifa_name = ruby_xmalloc(lstrlen(addr->AdapterName) + 1);
+ lstrcpy(ifa->ifa_name, addr->AdapterName);
+
+ if (addr->IfType & IF_TYPE_SOFTWARE_LOOPBACK)
+ ifa->ifa_flags |= IFF_LOOPBACK;
+ if (addr->OperStatus == IfOperStatusUp) {
+ ifa->ifa_flags |= IFF_UP;
+
+ if (addr->FirstUnicastAddress) {
+ IP_ADAPTER_UNICAST_ADDRESS *cur;
+ int added = 0;
+ for (cur = addr->FirstUnicastAddress; cur; cur = cur->Next) {
+ if (cur->Flags & IP_ADAPTER_ADDRESS_TRANSIENT ||
+ cur->DadState == IpDadStateDeprecated) {
+ continue;
+ }
+ if (added) {
+ prev = ifa;
+ ifa = ruby_xcalloc(1, sizeof(*ifa));
+ prev->ifa_next = ifa;
+ ifa->ifa_name =
+ ruby_xmalloc(lstrlen(addr->AdapterName) + 1);
+ lstrcpy(ifa->ifa_name, addr->AdapterName);
+ ifa->ifa_flags = prev->ifa_flags;
+ }
+ ifa->ifa_addr = ruby_xmalloc(cur->Address.iSockaddrLength);
+ memcpy(ifa->ifa_addr, cur->Address.lpSockaddr,
+ cur->Address.iSockaddrLength);
+ added = 1;
+ }
+ }
+ }
+
+ prev = ifa;
+ }
+
+ ruby_xfree(root);
+ return 0;
+}
+
+/* License: Ruby's */
+void
+freeifaddrs(struct ifaddrs *ifp)
+{
+ while (ifp) {
+ struct ifaddrs *next = ifp->ifa_next;
+ if (ifp->ifa_addr) ruby_xfree(ifp->ifa_addr);
+ if (ifp->ifa_name) ruby_xfree(ifp->ifa_name);
+ ruby_xfree(ifp);
+ ifp = next;
+ }
+}
+
//
// Networking stubs
//