summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-05-13 11:29:32 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-05-13 11:29:32 +0000
commitcb3fcdcdc3eeb4612c78d1fac10438214184642f (patch)
treee11b430371e7297b09e60f021bcc80016c4233b2 /win32
parentf1eadb0fb446418ac7b607a609cf19d9fd943f83 (diff)
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40693 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'win32')
-rw-r--r--win32/Makefile.sub2
-rw-r--r--win32/win32.c86
2 files changed, 84 insertions, 4 deletions
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
//