develooper Front page | perl.perl5.porters | Postings from June 2012

pp_select && obscure OS

Thread Next
From:
NormW
Date:
June 28, 2012 18:40
Subject:
pp_select && obscure OS
Message ID:
4FED077B.6000501@gknw.net
Hi,
Still trying to get pp_sys.c PP(pp_select) working for NetWare, so 
NetWare can work with apps like ASSP. As pp_select is in core,
this seemed the place to ask.

NetWare's fd_set struct has :

> {
>   int fd_count;  /* Count of fd sockets entered into fd_array */
>   int fd_array[FD_SETSIZE];
> }

AFAICT (Guess mostly) 3 bitmap arrays are passed into pp_select, which I 
think begin with socket 1 in the LSBit of the first byte.

The first task was to covert each bitmap to a string, get its len using: 
s = SvPV(sv, len) then step through each byte of the 'string', and, 
where there's a 'bit' set, push an int into the fd_array (using 
FD_SET()) that has the same binary value as the bit's position in the map.

This process for one one of the bitmaps looks like:

fd_set rdfds;
fd_set *prds = NULL;

> /* Reads */
> sv = SP[1];
> if (SvOK(sv) && SvCUR(sv)) {
>     assert(SvPOK(sv));
>     prds = &rdfds;
>     FD_ZERO(prds);
>     s = SvPV(sv, len);
>     sockno = 1;
>     for (i = 0; i < len; i++) {
>         chunk = s[i];
>         if (chunk) {
>             j = NBBY;
>             while(j) {
>                 if (chunk & 0x1) {
>                     if ((prds)->fd_count == FD_SETSIZE)
>                         Perl_croak(aTHX_ "Too many sockets passed to select():rds - Max ", FD_SETSIZE);
>                     FD_SET(sockno, prds);
>                     ninput++;
>                 }
>                 chunk = chunk >> 1;
>                 sockno++;
>                 j--;
>             }
>         }
>         else {
>             sockno += NBBY;
>         }
>     }
> }

This is repeated for each input array and select() called:

> /* Call select() */
> nfound = PerlSock_select(ninput + 1,
>                          prds,
>                          pwrs,
>                          pers,
>                          tbuf);

The final steps need to read the fd_arrays returned by select(), (I 
think) convert them back to bit maps, convert those to something Perl 
knows about (sv?) and return them to the calling program.

> /* read check out */
> if (prds) {
>     /* init output map */
>     FX_ZERO(pmap);
>     for (i = 1; i < rdfds.fd_count; i++) {
>          /* add int rdfds.fd_array[i] to map */
>          FX_SET(rdfds.fd_array[i], pmap);
>     }
>     /* save map to sv. */
>     sv_setpvn(sv, (char *)pmap, maxlen);
>     /* return output map */
>??     sv = SP[1];
>??     SvSETMAGIC(sv);
> }

The _BIG_ (obvious) questions for me are:

a) How to put each sv back into its right place in the stack?
b. Does stack item carry its own map or just pointers to the common map?
c. Is SvSETMAGIC() [a mystery] still needed here? (Perlguts is no help)
d. Any other glaring oversights?

I've attached the entire code block as I so far have it, all of which is 
in the public domain or otherwise adapted as 'necessary' from the 
original Perl code.

Any and all feedback welcome.
Regards,
Norm



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