Net-LibAsyncNS
view release on metacpan or search on metacpan
lib/Net/LibAsyncNS.xs view on Meta::CPAN
PREINIT:
char *hostname = NULL;
char *servicename = NULL;
STRLEN len;
struct addrinfo hints_s = { 0 };
asyncns_query_t *query;
CODE:
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;
}
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);
}
query = asyncns_getaddrinfo(self, hostname, servicename, &hints_s);
RETVAL = newSVsv(query_new(ST(0), self, query)->sv);
OUTPUT:
RETVAL
void
getaddrinfo_done(self, q)
Net::LibAsyncNS self
Net::LibAsyncNS::Query q
INIT:
int err;
struct addrinfo *res;
struct addrinfo *res_iter;
int n_res;
PPCODE:
err = asyncns_getaddrinfo_done(self, q->query, &res);
XPUSHs(gai_err_to_SV(err));
if(err) {
if(err != EAI_AGAIN)
SvREFCNT_dec(q->sv);
XSRETURN(1);
}
n_res = 0;
for(res_iter = res; res_iter; res_iter = res_iter->ai_next) {
HV *res_hv = newHV();
hv_store(res_hv, "family", 6, newSViv(res_iter->ai_family), 0);
hv_store(res_hv, "socktype", 8, newSViv(res_iter->ai_socktype), 0);
hv_store(res_hv, "protocol", 8, newSViv(res_iter->ai_protocol), 0);
hv_store(res_hv, "addr", 4, newSVpvn((char*)res_iter->ai_addr, res_iter->ai_addrlen), 0);
if(res_iter->ai_canonname)
hv_store(res_hv, "canonname", 9, newSVpv(res_iter->ai_canonname, 0), 0);
else
hv_store(res_hv, "canonname", 9, newSV(0), 0);
XPUSHs(sv_2mortal(newRV_noinc((SV*)res_hv)));
n_res++;
}
asyncns_freeaddrinfo(res);
SvREFCNT_dec(q->sv);
XSRETURN(1 + n_res);
SV *
getnameinfo(self, addr, flags, wanthost, wantserv)
Net::LibAsyncNS self
SV *addr
int flags
int wanthost
int wantserv
PREINIT:
char *sa;
STRLEN addr_len;
asyncns_query_t *query;
CODE:
if(!SvPOK(addr))
croak("addr is not a string");
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);
#ifdef HAVE_SOCKADDR_SA_LEN
((struct sockaddr *)sa)->sa_len = addr_len;
#endif
query = asyncns_getnameinfo(self, (struct sockaddr *)sa, addr_len, flags, wanthost, wantserv);
RETVAL = newSVsv(query_new(ST(0), self, query)->sv);
OUTPUT:
RETVAL
void
getnameinfo_done(self, q)
Net::LibAsyncNS self
Net::LibAsyncNS::Query q
PREINIT:
int err;
char host[1024];
char serv[256];
PPCODE:
err = asyncns_getnameinfo_done(self, q->query, host, sizeof(host), serv, sizeof(serv));
XPUSHs(gai_err_to_SV(err));
if(err) {
if(err != EAI_AGAIN)
SvREFCNT_dec(q->sv);
XSRETURN(1);
}
XPUSHs(sv_2mortal(newSVpv(host, 0)));
XPUSHs(sv_2mortal(newSVpv(serv, 0)));
SvREFCNT_dec(q->sv);
XSRETURN(3);
SV *
res_query(self, dname, class, type)
Net::LibAsyncNS self
char *dname
int class
int type
PREINIT:
asyncns_query_t *query;
CODE:
query = asyncns_res_query(self, dname, class, type);
RETVAL = newSVsv(query_new(ST(0), self, query)->sv);
OUTPUT:
RETVAL
SV *
res_search(self, dname, class, type)
Net::LibAsyncNS self
char *dname
int class
int type
PREINIT:
asyncns_query_t *query;
CODE:
query = asyncns_res_search(self, dname, class, type);
RETVAL = newSVsv(query_new(ST(0), self, query)->sv);
OUTPUT:
RETVAL
SV *
res_done(self, q)
Net::LibAsyncNS self
Net::LibAsyncNS::Query q
INIT:
int len;
unsigned char *answer;
PPCODE:
len = asyncns_res_done(self, q->query, &answer);
if(len < 0) {
if(-len != EAGAIN)
SvREFCNT_dec(q->sv);
errno = -len;
XSRETURN_UNDEF;
}
mXPUSHp(answer, len);
asyncns_freeanswer(answer);
SvREFCNT_dec(q->sv);
XSRETURN(1);
int
isdone(self, q)
Net::LibAsyncNS self
Net::LibAsyncNS::Query q
CODE:
RETVAL = asyncns_isdone(self, q->query);
OUTPUT:
RETVAL
SV *
getnext(self)
Net::LibAsyncNS self
PREINIT:
asyncns_query_t *query;
CODE:
query = asyncns_getnext(self);
if(!query)
XSRETURN_UNDEF;
RETVAL = newSVsv(asyncns_getuserdata(self, query));
OUTPUT:
RETVAL
void
cancel(self, q)
Net::LibAsyncNS self
Net::LibAsyncNS::Query q
CODE:
asyncns_cancel(self, q->query);
SvREFCNT_dec(q->sv);
void
setuserdata(self, q, data)
Net::LibAsyncNS self
Net::LibAsyncNS::Query q
SV *data
CODE:
if(q->userdata)
( run in 1.205 second using v1.01-cache-2.11-cpan-71847e10f99 )