diff options
author | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-05-13 11:29:32 +0000 |
---|---|---|
committer | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-05-13 11:29:32 +0000 |
commit | cb3fcdcdc3eeb4612c78d1fac10438214184642f (patch) | |
tree | e11b430371e7297b09e60f021bcc80016c4233b2 /win32 | |
parent | f1eadb0fb446418ac7b607a609cf19d9fd943f83 (diff) | |
download | ruby-cb3fcdcdc3eeb4612c78d1fac10438214184642f.tar.gz |
* 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.sub | 2 | ||||
-rw-r--r-- | win32/win32.c | 86 |
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 // |