diff options
Diffstat (limited to 'ext/Socket/Socket.xs')
-rw-r--r-- | ext/Socket/Socket.xs | 294 |
1 files changed, 147 insertions, 147 deletions
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 |