What I do is something like AV *results; results = newAV(); .... something = (AV *)SvRV(*other_av_thing); .... av_store(results,i, something); .... RETVAL = results; sv_2mortal((SV *)RETVAL);
On Wed, Jun 8, 2011 at 4:11 PM, NormW <no...@gknw.net> wrote: > Hi All, > AFAICT, I want to implement the following Perl call to XS code: > > my (@ro,@wo,@eo) = nw_select(\@ri,\@wi,\@ei,$wait); > > What I think I need is XS code to return the 3 LHS arrays or 'undef's as > appropriate. PerlXSTut Sample 7 seems a possible ideas source but alas it is > in the 'Coming soon' category at last check. > > BACKGROUND > > NetWare's fd_set struct is an FD_SETSIZE array of int's + a counter to > identify the last entry in the array, each int able to store a socket > handle. (NetWare select() does not work with file descriptors). This means, > AFAICT, it would be messy to patch the Perl pp_sselect code for NetWare, so > decided a separate XS module would better serve the task. > > Based on Perl XS docs and the XS code in the Perl source, I have put the > following XS code together, although for simplicity and compactness here > will only include the 'can_read' array... Any feedback regarding the > correctness of the code so far is much appreciated, as the NetWare debugger > is just as 'unique' and I would like the best chance to only have problems > in the Perl code when I try getting this to work! > > Lastly, based on Perl conventions, would the resulting module be more > appropriately named as IO::Select::NetWare or NetWare::Select, as I have > seen some Linux:: modules extant?? > > Now, finally, the XS code adapted/borrowed so far. > >> int >> nw_select(reads, writes, errors, wtime) >> SV* reads >> SV* writes >> SV* errors >> SV* wtime >> PREINIT: >> NV value; >> struct timeval timebuf; >> struct timeval *tbuf = &timebuf; >> SV *fd = NULL; >> int numfds = 0; >> int nfound = 0; >> int i; >> fd_set rdfds, wrfds, erfds; >> fd_set *prds = NULL, *pwrs = NULL, *pers = NULL; >> CODE: >> /* Wait Time */ >> if (SvOK(wtime)) { >> value = SvNV(wtime); >> if (value < 0.0) >> value = 0.0; >> timebuf.tv_sec = (long)value; >> value -= (NV)timebuf.tv_sec; >> timebuf.tv_usec = (long)(value * 1000000.0); >> } >> else >> tbuf = NULL; >> /* Reads */ >> if ((SvROK(reads)) && (SvTYPE(SvRV(reads)) == SVt_PVAV)) { >> prds = &rdfds; >> FD_ZERO(prds); >> while (av_len((AV*)reads) >= 0) { >> if (rdfds.fd_count >= FD_SETSIZE) >> croak("Too many sockets passed to NeWare::select(rd): Max ", >> FD_SETSIZE); >> fd = (SV*)av_shift((AV*)reads); >> FD_SET(SvIV(fd), prds); >> } >> numfds += rdfds.fd_count; >> } > > [....] >> >> /* Call LibC */ >> nfound = select( numfds + 1, prds, pwrs, pers, tbuf ); >> /* Reads */ >> if (prds == NULL) { >> ST(0) = &PL_sv_undef; >> } else { >> ST(0) = newAV(); >> sv_2mortal((SV*)ST(0)); >> for (i = 0 ; i < rdfds.fd_count ; i++) { >> sv_setpviv(fd, rdfds.fd_array[i]); >> av_push(ST(0), fd); >> } >> } > > Any and all feedback/comments welcome. > TIA, > Norm > >