diff options
author | Daniel Dragan <bulk88@hotmail.com> | 2015-09-10 03:36:36 -0400 |
---|---|---|
committer | Steve Hay <steve.m.hay@googlemail.com> | 2015-10-17 22:17:10 +0100 |
commit | e45189ae472830e78ec678c4bd0c35cbe52b10f8 (patch) | |
tree | 9ad4d65902a5ad8a71540e52846b9d2f6b6f618d /cpan/Socket | |
parent | 00ebc5bdc54d3943d2470f1053942f5849ab1a9d (diff) | |
download | perl-e45189ae472830e78ec678c4bd0c35cbe52b10f8.tar.gz |
Win32 inet_pton fallback misc fixes
-VC complains in inet_pton
"warning C4715: 'inet_pton' : not all control paths return a value"
this isn't much a problem since Socket.xs doesn't allow anything but
AF_INET and AF_INET6 on a XSUB level but fix the implementation anyway
since the previous cargo culted off the internet version has flaws, so
the Socket.xs version is usable elsewhere if necessery
-remove copying the string to C auto array, unix inet_ptoa requires null
terminated strings, so does WSAStringToAddress. WSAStringToAddress's docs
dont mention a maximum length to the input string, so no reason to
truncate and re-null terminate it
-MSDN's docs for WSAStringToAddress mentions that filling in sin_family
is required, even though lpAddress is an output arg, not input and a
duplicate of arg AddressFamily, there is probably some legacy protocol
driver out in the world that requires this
-static the functions, these fallbacks dont need to be visible in any other
.o, and with static they might be inlined/further optimized
-provide fallbacks for Visual C 6 (circa 1998) with very old headers that
were created before RFC 2553 was created
Diffstat (limited to 'cpan/Socket')
-rw-r--r-- | cpan/Socket/Socket.xs | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/cpan/Socket/Socket.xs b/cpan/Socket/Socket.xs index 5f60afaf82..52df483972 100644 --- a/cpan/Socket/Socket.xs +++ b/cpan/Socket/Socket.xs @@ -52,18 +52,40 @@ #endif #ifdef WIN32 -int inet_pton(int af, const char *src, void *dst) + +/* VC 6 with its original headers doesn't know about sockaddr_storage, VC 2003 does*/ +#ifndef _SS_MAXSIZE + +# define _SS_MAXSIZE 128 +# define _SS_ALIGNSIZE (sizeof(__int64)) + +# define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof (short)) +# define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (short) + _SS_PAD1SIZE \ + + _SS_ALIGNSIZE)) + +struct sockaddr_storage { + short ss_family; + char __ss_pad1[_SS_PAD1SIZE]; + __int64 __ss_align; + char __ss_pad2[_SS_PAD2SIZE]; +}; + +typedef int socklen_t; + +#define in6_addr in_addr6 + +#define INET_ADDRSTRLEN 22 +#define INET6_ADDRSTRLEN 65 + +#endif + +static int inet_pton(int af, const char *src, void *dst) { struct sockaddr_storage ss; int size = sizeof(ss); - char src_copy[INET6_ADDRSTRLEN+1]; + ss.ss_family = af; /* per MSDN */ - ZeroMemory(&ss, sizeof(ss)); - /* stupid non-const API */ - strncpy(src_copy, src, INET6_ADDRSTRLEN+1); - src_copy[INET6_ADDRSTRLEN] = 0; - - if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) != 0) + if (WSAStringToAddress((char*)src, af, NULL, (struct sockaddr *)&ss, &size) != 0) return 0; switch(af) { @@ -73,10 +95,13 @@ int inet_pton(int af, const char *src, void *dst) case AF_INET6: *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr; return 1; + default: + WSASetLastError(WSAEAFNOSUPPORT); + return -1; } } -const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) +static const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) { struct sockaddr_storage ss; unsigned long s = size; |