develooper Front page | perl.perl5.porters | Postings from September 2009

Re: Perl select() and fd_set differences

Thread Previous | Thread Next
From:
NormW
Date:
September 26, 2009 16:36
Subject:
Re: Perl select() and fd_set differences
Message ID:
4ABEA57C.3090902@gknw.net
G/Morning Nicholas,
Nicholas Clark wrote:
> On Thu, Sep 24, 2009 at 12:45:52PM +1000, NormW wrote:
>> Hi all,
>> Trying to port the ASSP app to NetWare, and found that NetWare has an 
>> fd_set typedef somewhat different to most:
>>
>>> typedef struct fd_set
>>> {
>>>   int   fd_count;
>>>   int   fd_array[FD_SETSIZE];
>>> } fd_set;
>>>
>> where fd_count is the numeric size of the active portion of the fd_array 
>> for both input and output. It does have the FD_CLR, FD_SET, FD_ZERO and 
>> FD_ISSET macro's.
>>
>> AFAICT this is a 'different' approach to that used by Perl pp_sselect(), 
>> (pp_sys.c) which uses a bit-map vector method.
> 
> However IO::Select is implemented using the builtin select, with parameters
> conforming to its interface documented in perlfunc.pod, so ultimately it is
> just calling down into pp_sselect
> 
>> Can anyone suggest what changes are needed to get IO::Select working 
>> with this 'fd_set' structure on Perl (5.8.9)? Any assistance would be 
>> much appreciated, and a working diff will be made available if I can get 
>> it working.
> 
> I'd suggest adding conditionally compiled code to pp_sselect to map from the
> interface that Perl-space expects into the structures that NetWare requires.
> 
> I assume that this will need 3 local structures, and some size-constrained
> copying.
> 
> Nicholas Clark
> 
Have done some digging in the docs and (so far) have the following vars:
>     AV * ar;
>     SV * fd;
>     NV value;
>     struct timeval timebuf;
>     struct timeval *tbuf = &timebuf;
>     int    maxlen = 0,nfound,i;
>     fd_set *rdfds,*wrfds, *exfds;

Instead of 'string' vector bit-maps, I'll assume that the first 3 
parameters are fd arrays, and move on from there.

The 'envisioned' block for getting the inbound 'canread' array should 
look something like (pseudocode where I get hazy):

>     ar = SP[1];
> 
>     if (defined ar and ArrayType) {
>         FD_ZERO(rdfds);
>         fd = av_pop(ar);
>         while (fd != &PL_sv_undef) {
>             FD_SET(SvIV(fd), rdfds);
>             if (rdfds->fd_count >= FD_SETSIZE)
>                 DIE(aTHX_ "Too many sockets passed to select(rd): Max FD_SETSIZE");
>             fd = av_pop(ar);
>         }
>         if (maxlen < rdfds->fd_count)
>             maxlen = rdfds->fd_count;
>     }
>     else
>         rdfds = NULL;

while the outgoing side for the same array might look like:

>     if (rdfds != NULL) {
>         av_clear(ar);
>         for ( i = 0 ; i < rdfds->fd_count ; i++) {
>             av_push(ar, sv_setpviv(fd,rdfds->fd_array[i]));
>         }
>         push(SP[1],ar);
>     }
>     else
>         push(SP[1],'undef');

AFAICT the 'timeout' code should be able to stay 'as-is', although not 
sure that select() doesn't just set the timer setting to zero on exit. 
Will have to research that.

Any assistance in getting this 'cleaned up' and 'workable' would be 
greatly appreciated!

And apologies for my previous mis-directed post.
Regards,
Norm

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About