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
>
>

Reply via email to