Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!think!ames!fxgrp!news From: grady@fxgrp.fx.com (Steven Grady) Newsgroups: comp.lang.perl Subject: do_select() bug Message-ID: <1989Dec16.044106.7924@fxgrp.fx.com> Date: 16 Dec 89 04:41:06 GMT Reply-To: grady@fxgrp.fx.com (Steven Grady) Organization: FXDevelopment, Mountain View, CA Lines: 82 do_select(), the function that implements UNIX select(), does not work properly. There are two problems. First, it uses the length of the vector (represented as a string internally) as the width of the bit field passed to select(). Unfortunately, it is including the '\0' terminator of the string as part of the length. With the width off by 8, the file descriptors examined are 8 higher than they should be. Second and more important, it does not work on suns. It does not use the FD_* macros. The representation it uses for the file descriptor bits, namely, a simple string, does not work at all (because the width on a sun must be a multiple of 32 bits). Here is a patch to fix do_select(). It is not very pretty, but it gets the job done. There is no compile flag to enable it, since it is not a complete patch anyway. This version will work on suns, but it won't work, for instance, on AIX (which uses "sellist" structures). The "correct" way to do things would be to avoid explicitly using perl vecs. I'd like to see a different interface to select() anyway. Perhaps something like: (@readready, @writeready, @exceptready, $timeleft) = select(@readhandles, @writehandles, @excepthandles, $timeout); where each of the arrays would be an array of expressions evaluating to file handles. The vec interface is pretty bogus (and doesn't work, under the current implementation). *** doio.c Fri Dec 15 20:26:16 1989 --- doio.c.BAK Fri Dec 15 20:07:44 1989 *************** *** 1510,1537 **** else tbuf = Null(struct timeval*); ! { ! fd_set fds[4]; ! register int i, j; ! for (j = 1; j <= 3; j++) { ! FD_ZERO(&fds[j]); ! if (st[sp+j]->str_ptr == NULL) continue; ! for (i = 0; i < (maxlen - 1) * 8; i++) { ! if (st[sp+j]->str_ptr[i/8] & (1 << (i % 8))) ! FD_SET(i, &fds[j]); ! } ! } ! nfound = select( ! (maxlen - 1) * 8, &fds[1], &fds[2], &fds[3], tbuf); ! for (j = 1; j <= 3; j++) { ! if (st[sp+j]->str_ptr == NULL) continue; ! bzero(st[sp+j]->str_ptr, (maxlen - 1)); ! for (i = 0; i < (maxlen - 1) * 8; i++) { ! if (FD_ISSET(i, &fds[j])) ! st[sp+j]->str_ptr[i/8] |= (1 << (i % 8)); ! } ! } ! } st[++sp] = str_static(&str_no); str_numset(st[sp], (double)nfound); --- 1510,1521 ---- else tbuf = Null(struct timeval*); ! nfound = select( ! maxlen * 8, ! st[sp+1]->str_ptr, ! st[sp+2]->str_ptr, ! st[sp+3]->str_ptr, ! tbuf); st[++sp] = str_static(&str_no); str_numset(st[sp], (double)nfound); -- Steven ...!ucbvax!grady grady@postgres.berkeley.edu Spock was waiting for them when they got to the conference room. "Captain, I've run the data we collected through the computer." "Well, Spock, you must be a very proud young man. So what's the deal with these council weasels?"