diff options
author | Paul "LeoNerd" Evans <leonerd@leonerd.org.uk> | 2011-01-24 18:55:38 +0000 |
---|---|---|
committer | Jesse Vincent <jesse@bestpractical.com> | 2011-01-29 14:18:47 -0500 |
commit | 0f41f5e29630b6c28287818a9865848423359f34 (patch) | |
tree | 1a10c54a43118fb3ccab4e57a759d78d8f628f7d /ext/Socket | |
parent | cae12adc651d7daf435d322e4247df4191bc18a7 (diff) | |
download | perl-0f41f5e29630b6c28287818a9865848423359f34.tar.gz |
Reindent recent IPv6/getaddrinfo code consistently with the rest of the files
Diffstat (limited to 'ext/Socket')
-rw-r--r-- | ext/Socket/Socket.pm | 360 | ||||
-rw-r--r-- | ext/Socket/Socket.xs | 294 |
2 files changed, 327 insertions, 327 deletions
diff --git a/ext/Socket/Socket.pm b/ext/Socket/Socket.pm index 3e4d56ae81..36551b1626 100644 --- a/ext/Socket/Socket.pm +++ b/ext/Socket/Socket.pm @@ -588,49 +588,49 @@ XSLoader::load(); my %errstr; if( !defined &getaddrinfo ) { - require Scalar::Util; - - *getaddrinfo = \&fake_getaddrinfo; - *getnameinfo = \&fake_getnameinfo; - - # These numbers borrowed from GNU libc's implementation, but since - # they're only used by our emulation, it doesn't matter if the real - # platform's values differ - my %constants = ( - AI_PASSIVE => 1, - AI_CANONNAME => 2, - AI_NUMERICHOST => 4, - # RFC 2553 doesn't define this but Linux does - lets be nice and - # provide it since we can - AI_NUMERICSERV => 1024, - - EAI_BADFLAGS => -1, - EAI_NONAME => -2, - EAI_NODATA => -5, - EAI_FAMILY => -6, - EAI_SERVICE => -8, - - NI_NUMERICHOST => 1, - NI_NUMERICSERV => 2, - NI_NAMEREQD => 8, - NI_DGRAM => 16, - ); - - foreach my $name ( keys %constants ) { - my $value = $constants{$name}; - - no strict 'refs'; - defined &$name or *$name = sub () { $value }; - } - - %errstr = ( - # These strings from RFC 2553 - EAI_BADFLAGS() => "invalid value for ai_flags", - EAI_NONAME() => "nodename nor servname provided, or not known", - EAI_NODATA() => "no address associated with nodename", - EAI_FAMILY() => "ai_family not supported", - EAI_SERVICE() => "servname not supported for ai_socktype", - ); + require Scalar::Util; + + *getaddrinfo = \&fake_getaddrinfo; + *getnameinfo = \&fake_getnameinfo; + + # These numbers borrowed from GNU libc's implementation, but since + # they're only used by our emulation, it doesn't matter if the real + # platform's values differ + my %constants = ( + AI_PASSIVE => 1, + AI_CANONNAME => 2, + AI_NUMERICHOST => 4, + # RFC 2553 doesn't define this but Linux does - lets be nice and + # provide it since we can + AI_NUMERICSERV => 1024, + + EAI_BADFLAGS => -1, + EAI_NONAME => -2, + EAI_NODATA => -5, + EAI_FAMILY => -6, + EAI_SERVICE => -8, + + NI_NUMERICHOST => 1, + NI_NUMERICSERV => 2, + NI_NAMEREQD => 8, + NI_DGRAM => 16, + ); + + foreach my $name ( keys %constants ) { + my $value = $constants{$name}; + + no strict 'refs'; + defined &$name or *$name = sub () { $value }; + } + + %errstr = ( + # These strings from RFC 2553 + EAI_BADFLAGS() => "invalid value for ai_flags", + EAI_NONAME() => "nodename nor servname provided, or not known", + EAI_NODATA() => "no address associated with nodename", + EAI_FAMILY() => "ai_family not supported", + EAI_SERVICE() => "servname not supported for ai_socktype", + ); } # The following functions are used if the system does not have a @@ -643,151 +643,151 @@ my $REGEXP_IPv4_DOTTEDQUAD = qr/$REGEXP_IPv4_DECIMAL\.$REGEXP_IPv4_DECIMAL\.$REG sub fake_makeerr { - my ( $errno ) = @_; - my $errstr = $errno == 0 ? "" : ( $errstr{$errno} || $errno ); - return Scalar::Util::dualvar( $errno, $errstr ); + my ( $errno ) = @_; + my $errstr = $errno == 0 ? "" : ( $errstr{$errno} || $errno ); + return Scalar::Util::dualvar( $errno, $errstr ); } sub fake_getaddrinfo { - my ( $node, $service, $hints ) = @_; - - $node = "" unless defined $node; - - $service = "" unless defined $service; - - my ( $family, $socktype, $protocol, $flags ) = @$hints{qw( family socktype protocol flags )}; - - $family ||= Socket::AF_INET(); # 0 == AF_UNSPEC, which we want too - $family == Socket::AF_INET() or return fake_makeerr( EAI_FAMILY() ); - - $socktype ||= 0; - - $protocol ||= 0; - - $flags ||= 0; - - my $flag_passive = $flags & AI_PASSIVE(); $flags &= ~AI_PASSIVE(); - my $flag_canonname = $flags & AI_CANONNAME(); $flags &= ~AI_CANONNAME(); - my $flag_numerichost = $flags & AI_NUMERICHOST(); $flags &= ~AI_NUMERICHOST(); - my $flag_numericserv = $flags & AI_NUMERICSERV(); $flags &= ~AI_NUMERICSERV(); - - $flags == 0 or return fake_makeerr( EAI_BADFLAGS() ); - - $node eq "" and $service eq "" and return fake_makeerr( EAI_NONAME() ); - - my $canonname; - my @addrs; - if( $node ne "" ) { - return fake_makeerr( EAI_NONAME() ) if( $flag_numerichost and $node !~ m/^$REGEXP_IPv4_DOTTEDQUAD$/ ); - ( $canonname, undef, undef, undef, @addrs ) = gethostbyname( $node ); - defined $canonname or return fake_makeerr( EAI_NONAME() ); - - undef $canonname unless $flag_canonname; - } - else { - $addrs[0] = $flag_passive ? Socket::inet_aton( "0.0.0.0" ) - : Socket::inet_aton( "127.0.0.1" ); - } - - my @ports; # Actually ARRAYrefs of [ socktype, protocol, port ] - my $protname = ""; - if( $protocol ) { - $protname = getprotobynumber( $protocol ); - } - - if( $service ne "" and $service !~ m/^\d+$/ ) { - return fake_makeerr( EAI_NONAME() ) if( $flag_numericserv ); - getservbyname( $service, $protname ) or return fake_makeerr( EAI_SERVICE() ); - } - - foreach my $this_socktype ( Socket::SOCK_STREAM(), Socket::SOCK_DGRAM(), Socket::SOCK_RAW() ) { - next if $socktype and $this_socktype != $socktype; - - my $this_protname = "raw"; - $this_socktype == Socket::SOCK_STREAM() and $this_protname = "tcp"; - $this_socktype == Socket::SOCK_DGRAM() and $this_protname = "udp"; - - next if $protname and $this_protname ne $protname; - - my $port; - if( $service ne "" ) { - if( $service =~ m/^\d+$/ ) { - $port = "$service"; - } - else { - ( undef, undef, $port, $this_protname ) = getservbyname( $service, $this_protname ); - next unless defined $port; - } - } - else { - $port = 0; - } - - push @ports, [ $this_socktype, scalar getprotobyname( $this_protname ) || 0, $port ]; - } - - my @ret; - foreach my $addr ( @addrs ) { - foreach my $portspec ( @ports ) { - my ( $socktype, $protocol, $port ) = @$portspec; - push @ret, { - family => $family, - socktype => $socktype, - protocol => $protocol, - addr => Socket::pack_sockaddr_in( $port, $addr ), - canonname => $canonname, - }; - } - } - - return ( fake_makeerr( 0 ), @ret ); + my ( $node, $service, $hints ) = @_; + + $node = "" unless defined $node; + + $service = "" unless defined $service; + + my ( $family, $socktype, $protocol, $flags ) = @$hints{qw( family socktype protocol flags )}; + + $family ||= Socket::AF_INET(); # 0 == AF_UNSPEC, which we want too + $family == Socket::AF_INET() or return fake_makeerr( EAI_FAMILY() ); + + $socktype ||= 0; + + $protocol ||= 0; + + $flags ||= 0; + + my $flag_passive = $flags & AI_PASSIVE(); $flags &= ~AI_PASSIVE(); + my $flag_canonname = $flags & AI_CANONNAME(); $flags &= ~AI_CANONNAME(); + my $flag_numerichost = $flags & AI_NUMERICHOST(); $flags &= ~AI_NUMERICHOST(); + my $flag_numericserv = $flags & AI_NUMERICSERV(); $flags &= ~AI_NUMERICSERV(); + + $flags == 0 or return fake_makeerr( EAI_BADFLAGS() ); + + $node eq "" and $service eq "" and return fake_makeerr( EAI_NONAME() ); + + my $canonname; + my @addrs; + if( $node ne "" ) { + return fake_makeerr( EAI_NONAME() ) if( $flag_numerichost and $node !~ m/^$REGEXP_IPv4_DOTTEDQUAD$/ ); + ( $canonname, undef, undef, undef, @addrs ) = gethostbyname( $node ); + defined $canonname or return fake_makeerr( EAI_NONAME() ); + + undef $canonname unless $flag_canonname; + } + else { + $addrs[0] = $flag_passive ? Socket::inet_aton( "0.0.0.0" ) + : Socket::inet_aton( "127.0.0.1" ); + } + + my @ports; # Actually ARRAYrefs of [ socktype, protocol, port ] + my $protname = ""; + if( $protocol ) { + $protname = getprotobynumber( $protocol ); + } + + if( $service ne "" and $service !~ m/^\d+$/ ) { + return fake_makeerr( EAI_NONAME() ) if( $flag_numericserv ); + getservbyname( $service, $protname ) or return fake_makeerr( EAI_SERVICE() ); + } + + foreach my $this_socktype ( Socket::SOCK_STREAM(), Socket::SOCK_DGRAM(), Socket::SOCK_RAW() ) { + next if $socktype and $this_socktype != $socktype; + + my $this_protname = "raw"; + $this_socktype == Socket::SOCK_STREAM() and $this_protname = "tcp"; + $this_socktype == Socket::SOCK_DGRAM() and $this_protname = "udp"; + + next if $protname and $this_protname ne $protname; + + my $port; + if( $service ne "" ) { + if( $service =~ m/^\d+$/ ) { + $port = "$service"; + } + else { + ( undef, undef, $port, $this_protname ) = getservbyname( $service, $this_protname ); + next unless defined $port; + } + } + else { + $port = 0; + } + + push @ports, [ $this_socktype, scalar getprotobyname( $this_protname ) || 0, $port ]; + } + + my @ret; + foreach my $addr ( @addrs ) { + foreach my $portspec ( @ports ) { + my ( $socktype, $protocol, $port ) = @$portspec; + push @ret, { + family => $family, + socktype => $socktype, + protocol => $protocol, + addr => Socket::pack_sockaddr_in( $port, $addr ), + canonname => $canonname, + }; + } + } + + return ( fake_makeerr( 0 ), @ret ); } sub fake_getnameinfo { - my ( $addr, $flags ) = @_; - - my ( $port, $inetaddr ); - eval { ( $port, $inetaddr ) = Socket::unpack_sockaddr_in( $addr ) } - or return fake_makeerr( EAI_FAMILY() ); - - my $family = Socket::AF_INET(); - - $flags ||= 0; - - my $flag_numerichost = $flags & NI_NUMERICHOST(); $flags &= ~NI_NUMERICHOST(); - my $flag_numericserv = $flags & NI_NUMERICSERV(); $flags &= ~NI_NUMERICSERV(); - my $flag_namereqd = $flags & NI_NAMEREQD(); $flags &= ~NI_NAMEREQD(); - my $flag_dgram = $flags & NI_DGRAM() ; $flags &= ~NI_DGRAM(); - - $flags == 0 or return fake_makeerr( EAI_BADFLAGS() ); - - my $node; - if( $flag_numerichost ) { - $node = Socket::inet_ntoa( $inetaddr ); - } - else { - $node = gethostbyaddr( $inetaddr, $family ); - if( !defined $node ) { - return fake_makeerr( EAI_NONAME() ) if $flag_namereqd; - $node = Socket::inet_ntoa( $inetaddr ); - } - } - - my $service; - if( $flag_numericserv ) { - $service = "$port"; - } - else { - my $protname = $flag_dgram ? "udp" : ""; - $service = getservbyport( $port, $protname ); - if( !defined $service ) { - $service = "$port"; - } - } - - return ( fake_makeerr( 0 ), $node, $service ); + my ( $addr, $flags ) = @_; + + my ( $port, $inetaddr ); + eval { ( $port, $inetaddr ) = Socket::unpack_sockaddr_in( $addr ) } + or return fake_makeerr( EAI_FAMILY() ); + + my $family = Socket::AF_INET(); + + $flags ||= 0; + + my $flag_numerichost = $flags & NI_NUMERICHOST(); $flags &= ~NI_NUMERICHOST(); + my $flag_numericserv = $flags & NI_NUMERICSERV(); $flags &= ~NI_NUMERICSERV(); + my $flag_namereqd = $flags & NI_NAMEREQD(); $flags &= ~NI_NAMEREQD(); + my $flag_dgram = $flags & NI_DGRAM() ; $flags &= ~NI_DGRAM(); + + $flags == 0 or return fake_makeerr( EAI_BADFLAGS() ); + + my $node; + if( $flag_numerichost ) { + $node = Socket::inet_ntoa( $inetaddr ); + } + else { + $node = gethostbyaddr( $inetaddr, $family ); + if( !defined $node ) { + return fake_makeerr( EAI_NONAME() ) if $flag_namereqd; + $node = Socket::inet_ntoa( $inetaddr ); + } + } + + my $service; + if( $flag_numericserv ) { + $service = "$port"; + } + else { + my $protname = $flag_dgram ? "udp" : ""; + $service = getservbyport( $port, $protname ); + if( !defined $service ) { + $service = "$port"; + } + } + + return ( fake_makeerr( 0 ), $node, $service ); } 1; diff --git a/ext/Socket/Socket.xs b/ext/Socket/Socket.xs index d91fcab2da..0dda808945 100644 --- a/ext/Socket/Socket.xs +++ b/ext/Socket/Socket.xs @@ -223,183 +223,183 @@ not_here(const char *s) #ifdef HAS_GETADDRINFO static SV *err_to_SV(pTHX_ int err) { - SV *ret = sv_newmortal(); - SvUPGRADE(ret, SVt_PVNV); + SV *ret = sv_newmortal(); + SvUPGRADE(ret, SVt_PVNV); - if(err) { - const char *error = gai_strerror(err); - sv_setpv(ret, error); - } - else { - sv_setpv(ret, ""); - } + if(err) { + const char *error = gai_strerror(err); + sv_setpv(ret, error); + } + else { + sv_setpv(ret, ""); + } - SvIV_set(ret, err); SvIOK_on(ret); + SvIV_set(ret, err); SvIOK_on(ret); - return ret; + return ret; } static void xs_getaddrinfo(pTHX_ CV *cv) { - dVAR; - dXSARGS; - - SV *host; - SV *service; - SV *hints; - - char *hostname = NULL; - char *servicename = NULL; - STRLEN len; - struct addrinfo hints_s; - struct addrinfo *res; - struct addrinfo *res_iter; - int err; - int n_res; - - if(items > 3) - croak_xs_usage(cv, "host, service, hints"); - - SP -= items; - - if(items < 1) - host = &PL_sv_undef; - else - host = ST(0); - - if(items < 2) - service = &PL_sv_undef; - else - service = ST(1); - - if(items < 3) - hints = NULL; - else - hints = ST(2); - - SvGETMAGIC(host); - if(SvOK(host)) { - hostname = SvPV_nomg(host, len); - if (!len) - hostname = NULL; - } - - SvGETMAGIC(service); - if(SvOK(service)) { - servicename = SvPV_nomg(service, len); - if (!len) - servicename = NULL; - } - - Zero(&hints_s, sizeof hints_s, char); - - if(hints && SvOK(hints)) { - HV *hintshash; - SV **valp; - - if(!SvROK(hints) || SvTYPE(SvRV(hints)) != SVt_PVHV) - croak("hints is not a HASH reference"); - - hintshash = (HV*)SvRV(hints); - - if((valp = hv_fetch(hintshash, "flags", 5, 0)) != NULL) - hints_s.ai_flags = SvIV(*valp); - if((valp = hv_fetch(hintshash, "family", 6, 0)) != NULL) - hints_s.ai_family = SvIV(*valp); - if((valp = hv_fetch(hintshash, "socktype", 8, 0)) != NULL) - hints_s.ai_socktype = SvIV(*valp); - if((valp = hv_fetch(hintshash, "protocol", 8, 0)) != NULL) - hints_s.ai_protocol = SvIV(*valp); - } - - err = getaddrinfo(hostname, servicename, &hints_s, &res); - - XPUSHs(err_to_SV(aTHX_ err)); - - if(err) - XSRETURN(1); - - n_res = 0; - for(res_iter = res; res_iter; res_iter = res_iter->ai_next) { - HV *res_hv = newHV(); - - (void)hv_stores(res_hv, "family", newSViv(res_iter->ai_family)); - (void)hv_stores(res_hv, "socktype", newSViv(res_iter->ai_socktype)); - (void)hv_stores(res_hv, "protocol", newSViv(res_iter->ai_protocol)); - - (void)hv_stores(res_hv, "addr", newSVpvn((char*)res_iter->ai_addr, res_iter->ai_addrlen)); - - if(res_iter->ai_canonname) - (void)hv_stores(res_hv, "canonname", newSVpv(res_iter->ai_canonname, 0)); - else - (void)hv_stores(res_hv, "canonname", newSV(0)); - - XPUSHs(sv_2mortal(newRV_noinc((SV*)res_hv))); - n_res++; - } - - freeaddrinfo(res); - - XSRETURN(1 + n_res); + dVAR; + dXSARGS; + + SV *host; + SV *service; + SV *hints; + + char *hostname = NULL; + char *servicename = NULL; + STRLEN len; + struct addrinfo hints_s; + struct addrinfo *res; + struct addrinfo *res_iter; + int err; + int n_res; + + if(items > 3) + croak_xs_usage(cv, "host, service, hints"); + + SP -= items; + + if(items < 1) + host = &PL_sv_undef; + else + host = ST(0); + + if(items < 2) + service = &PL_sv_undef; + else + service = ST(1); + + if(items < 3) + hints = NULL; + else + hints = ST(2); + + SvGETMAGIC(host); + if(SvOK(host)) { + hostname = SvPV_nomg(host, len); + if (!len) + hostname = NULL; + } + + SvGETMAGIC(service); + if(SvOK(service)) { + servicename = SvPV_nomg(service, len); + if (!len) + servicename = NULL; + } + + Zero(&hints_s, sizeof hints_s, char); + + if(hints && SvOK(hints)) { + HV *hintshash; + SV **valp; + + if(!SvROK(hints) || SvTYPE(SvRV(hints)) != SVt_PVHV) + croak("hints is not a HASH reference"); + + hintshash = (HV*)SvRV(hints); + + if((valp = hv_fetch(hintshash, "flags", 5, 0)) != NULL) + hints_s.ai_flags = SvIV(*valp); + if((valp = hv_fetch(hintshash, "family", 6, 0)) != NULL) + hints_s.ai_family = SvIV(*valp); + if((valp = hv_fetch(hintshash, "socktype", 8, 0)) != NULL) + hints_s.ai_socktype = SvIV(*valp); + if((valp = hv_fetch(hintshash, "protocol", 8, 0)) != NULL) + hints_s.ai_protocol = SvIV(*valp); + } + + err = getaddrinfo(hostname, servicename, &hints_s, &res); + + XPUSHs(err_to_SV(aTHX_ err)); + + if(err) + XSRETURN(1); + + n_res = 0; + for(res_iter = res; res_iter; res_iter = res_iter->ai_next) { + HV *res_hv = newHV(); + + (void)hv_stores(res_hv, "family", newSViv(res_iter->ai_family)); + (void)hv_stores(res_hv, "socktype", newSViv(res_iter->ai_socktype)); + (void)hv_stores(res_hv, "protocol", newSViv(res_iter->ai_protocol)); + + (void)hv_stores(res_hv, "addr", newSVpvn((char*)res_iter->ai_addr, res_iter->ai_addrlen)); + + if(res_iter->ai_canonname) + (void)hv_stores(res_hv, "canonname", newSVpv(res_iter->ai_canonname, 0)); + else + (void)hv_stores(res_hv, "canonname", newSV(0)); + + XPUSHs(sv_2mortal(newRV_noinc((SV*)res_hv))); + n_res++; + } + + freeaddrinfo(res); + + XSRETURN(1 + n_res); } #endif #ifdef HAS_GETNAMEINFO static void xs_getnameinfo(pTHX_ CV *cv) { - dVAR; - dXSARGS; + dVAR; + dXSARGS; - SV *addr; - int flags; + SV *addr; + int flags; - char host[1024]; - char serv[256]; - char *sa; /* we'll cast to struct sockaddr * when necessary */ - STRLEN addr_len; - int err; + char host[1024]; + char serv[256]; + char *sa; /* we'll cast to struct sockaddr * when necessary */ + STRLEN addr_len; + int err; - if(items < 1 || items > 2) - croak_xs_usage(cv, "addr, flags=0"); + if(items < 1 || items > 2) + croak_xs_usage(cv, "addr, flags=0"); - SP -= items; + SP -= items; - addr = ST(0); + addr = ST(0); - if(items < 2) - flags = 0; - else - flags = SvIV(ST(1)); + if(items < 2) + flags = 0; + else + flags = SvIV(ST(1)); - if(!SvPOK(addr)) - croak("addr is not a string"); + if(!SvPOK(addr)) + croak("addr is not a string"); - addr_len = SvCUR(addr); + addr_len = SvCUR(addr); - /* We need to ensure the sockaddr is aligned, because a random SvPV might - * not be due to SvOOK */ - Newx(sa, addr_len, char); - Copy(SvPV_nolen(addr), sa, addr_len, char); + /* We need to ensure the sockaddr is aligned, because a random SvPV might + * not be due to SvOOK */ + Newx(sa, addr_len, char); + Copy(SvPV_nolen(addr), sa, addr_len, char); #ifdef HAS_SOCKADDR_SA_LEN - ((struct sockaddr *)sa)->sa_len = addr_len; + ((struct sockaddr *)sa)->sa_len = addr_len; #endif - err = getnameinfo((struct sockaddr *)sa, addr_len, - host, sizeof(host), - serv, sizeof(serv), - flags); + err = getnameinfo((struct sockaddr *)sa, addr_len, + host, sizeof(host), + serv, sizeof(serv), + flags); - Safefree(sa); + Safefree(sa); - XPUSHs(err_to_SV(aTHX_ err)); + XPUSHs(err_to_SV(aTHX_ err)); - if(err) - XSRETURN(1); + if(err) + XSRETURN(1); - XPUSHs(sv_2mortal(newSVpv(host, 0))); - XPUSHs(sv_2mortal(newSVpv(serv, 0))); + XPUSHs(sv_2mortal(newSVpv(host, 0))); + XPUSHs(sv_2mortal(newSVpv(serv, 0))); - XSRETURN(3); + XSRETURN(3); } #endif |