althepal has asked for the wisdom of the Perl Monks concerning the following question:

I'm using select(4 arg) and sysread() to read a socket. I've noticed some strange behavior that I didn't expect, and I'm looking for some insight.

First of all, I've noticed that when a signal comes in (e.g. HUP) during select(), the function returns -1. I haven't seen this documented anywhere. Is this new to perl5.8? I know signal handling has been improved in 5.8, is there any detailed doc on this?

Also, I always thought that sysread() was non-blocking, but when there is no data to read, sysread() blocks. Is there any way to grab whatever data is on the socket (if any), without blocking? I know it sounds funny, but I don't completely trust select() to tell me that there's something to read. I want to double check when select() times out that there really is nothing on the socket. Should I just use an alarm to time out sysread()?

Finally, I was told a few days ago that sysread() should be given a value to read equivalent to my system's buffer size. Is this information correct? I don't see this documented anywhere? Can it hurt to tell sysread() to read in a much larger value? What if I tell it to read in 100K? Will chaos ensue? Is my system's buffer size the maximum size that sysread() will read?

Replies are listed 'Best First'.
Re: select() and sysread()
by salva (Canon) on Apr 27, 2005 at 12:58 UTC
    from select docs on perlfunc: Note that whether "select" gets restarted after signals (say, SIGALRM) is implementation-dependent.

    So, in some OSs, select will be transparently restarted after some signal is handled, in others it will return an error, and in perl the error is materialized as -1;

    Usually you can ignore signals just running select inside a while loop:

    1 while (($fn=select(...))>0);
    and don't bother thinking that select is not reliable, it is, you just have to check its bit vector arguments to see which files are available for reading, writing or error... or use IO::Select::select that has a more friendly interface.
Re: select() and sysread()
by polettix (Vicar) on Apr 27, 2005 at 13:05 UTC
    From perldoc -f select:
    This calls the select(2) system call with the bit masks specified...
    I bet that this tries to redirect you to the system select manpage (man 2 select), so you'll find the documentation there.
    Note that whether "select" gets restarted after signals (say, SIGALRM) + is implementation-dependent.
    When a signal arrive, it's likely that the select() function exits with "-1" (error), and in C you'd peruse errno to see if it's set to EINTR. I guess that in Perl a good look to $! will give you the same information.
    Also, I always thought that sysread() was non-blocking, but when there is no data to read, sysread() blocks.
    AFAIK, read() and similars have always been blocking, and you have to explicitly set unblocking mode to get what you want (try to see something in Fcntl and related documentation). Unluckly my mileage in Perl is quite short in these arguments, but I'd stick to select() even if i were programming in C. Given the fact that interruptions result in EINTR, you can easily restart the wait process.

    Regarding the last question, I would not expect your program to bomb out if you pass a bigger buffer: it would be quite strange if such a behaviour would not be documented. The maximum (or minimum :) I can expect is that you won't get 100k of data at one time and no more, but I haven't tried it.

    Flavio (perl -e 'print(scalar(reverse("\nti.xittelop\@oivalf")))')

    Don't fool yourself.
Re: select() and sysread()
by zentara (Cardinal) on Apr 28, 2005 at 12:23 UTC
    There is an interesting technique in "perldoc -q filehandle" in the section "How can I tell whether there's a character waiting on a filehandle? ". If you use the technique described, you can test for how many bytes are ready to be read before you read them, then you can tell sysread to read that many bytes. It works on pipes, but I havn't tried it on sockets, but since it's looking at the buffer, it would seem to be workable. There is example code at IPC3 buffer limit problem.

    I'm not really a human, but I play one on earth. flash japh