Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

select($rin,undef,undef,undef) only blocking once

by rabbit7 (Initiate)
on Jul 26, 2005 at 09:06 UTC ( #478096=perlquestion: print w/replies, xml ) Need Help??

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

select() is only blocking the first time it gets executed. I want it to block everytime though, what am i doing wrong ?
#!/usr/bin/perl -w use strict; use POSIX qw(mkfifo); use Fcntl qw(O_RDONLY O_NONBLOCK); my $fifofile = "fifo"; my $inputbuf; unlink($fifofile); mkfifo($fifofile, 0666) or die (' can\'t create FIFO:'.$fifofile); sysopen(FIFOFD, $fifofile, O_RDONLY | O_NONBLOCK ) or die ("can\'t rea +d FIFO:'.$fifofile"); while (1){ my $rin =''; vec($rin,0,1)=1; vec($rin,fileno(FIFOFD),1)=1; select( $rin, undef, undef, undef ); print "select returning\n"; my $fromfifo; while ( sysread(FIFOFD, $fromfifo, 1) == 1 ){ $inputbuf .= $fromfifo ; } my $command; my $index; while ( $index = index($inputbuf,"\n" )+1 ){ my $command = substr($inputbuf,0,$index,""); if ( defined ($command) ) { print $command; } } }

Replies are listed 'Best First'.
Re: select($rin,undef,undef,undef) only blocking once
by Tanalis (Curate) on Jul 26, 2005 at 10:14 UTC
    The select function makes use of the C select(2) system call.

    As the docs for select(2) state, file descriptors "will be watched to see if characters become available for reading (more precisely, to see if a read will not block ... a file descriptor is also ready on end-of-file)"

    Once you've read data from the pipe once, the file pointer will be pointing at EOF, and hence the select call will always return ready.

    In a situation like this, I would consider using a blocking read over blocking on file readiness; alternatively, look into the use of seek or sysseek to try to clear the file's EOF condition (which may not be possible - I can't test it here).

    Hope that helps.

    -- Foxcub

    Update: rabbit7 indicates that sysseek doesn't work with a fifo. Updated to reflect this.
      sysseek() does not work on a FIFO it seems.
      would it be a solution to reopen the FIFO before the select statement ?
      it works, but i dont think that is the proper way....
        It'd seem to be.

        I still favour a blocking read over blocking using select, though - you're using two system calls (which are relatively expensive) to do the job of one (unless there's something I'm missing).

        Paraphrasing the Cookbook a little, replacing your loop with

        for( ;; ) { open FIFO; "<", $fifofile or die $!; my $buf = <FIFO>; # blocks next unless defined $buf; chomp $buf; print $buf; close FIFO; }
        would seem to work as expected.

        Just as a final point, I'm not 100% sure what you're trying to achieve with your calls to index and substr - all you seem to be doing there is stripping the newline, which you can achieve using chomp.

        Hope that helps.

Re: select($rin,undef,undef,undef) only blocking once
by (anonymized user) (Curate) on Jul 26, 2005 at 09:40 UTC
    select() only blocks until the filehandle is ready (from performing an implicit autoflush). Therefore, once this has happened the first time, nothing has changed in your loop to prevent the filehandle being ready instantly the second time around, so the blocking occurs thereafter for zero time.

    Update: I note that in the code the filehandle stays set to empty, which would default it to standard input - this could be creating an additional obstacle..

    Hope this helps,


    One world, one people

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://478096]
Approved by Tanalis
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (2)
As of 2021-04-22 03:07 GMT
Find Nodes?
    Voting Booth?

    No recent polls found