[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Perl Q: timed input





Hi everybody,

I'm trying to provide a non-blocking input in my perl program.
Somehow, it doesn't work.

Objective: read STDIN with a blocking timeout, to be able to perform
certain actions if there was no input in a certain period of time.

Program: A very simplified program is attached before

Implementation: as suggested everywhere: using alarm().

Problem indication: I have a file, containing 22 lines. To test a
program, I use the following command:

	tail -f file | ./myprogram

I expect my program to show a tail of the file, and then to block on
reading with periodical timeouts. In any case, there should be no more
input than the tail of the file.

Instead, that's what I'm getting (each line in a file is merely a line
number and a word line):


$ tail -f test.IN | ./myprogram 
*** reading... done
==================> line:     13        line
*** reading... done
==================> line:     14        line
*** reading... done
==================> line:     15        line
*** reading... done
==================> line:     16        line
*** reading... done
==================> line:     17        line
*** reading... done
==================> line:     18        line
*** reading... done
==================> line:     19        line
*** reading... done
==================> line:     20        line
*** reading... done
==================> line:     21        line
*** reading... done
==================> line:     22        line
*** reading... 

	< this is where read is blocked -- my comment >

*** reading... done
==================> line:     13        line
*** reading... done
==================> line:     14        line
*** reading... done
==================> line:     15        line
*** reading... done
==================> line:     16        line
*** reading... done
==================> line:     17        line
*** reading... done
==================> line:     18        line
*** reading... done
==================> line:     19        line
*** reading... done
==================> line:     20        line
*** reading... done
==================> line:     21        line
*** reading... done
==================> line:     22        line
*** reading... 

	< blocked again -- my comment >

	etc

So, after the timeout, the program "reads" the very same contents it
had read before the timeout!!!

I am sure I'm doing something wrong. Chances are, the <> operation is
not signal-safe, yet I found no proof to it.

Please help,

Thanks in advance.

PPS. The program code:

=====================================================================
#!/usr/bin/perl


$period = 180;
$timeout = 60;                  # read timeout


$oldfh = select(STDIN); $| = 1; select($oldfh);
$oldfh = select(STDERR); $| = 1; select($oldfh);
$oldfh = select(STDOUT); $| = 1; select($oldfh);


while (1) {
    eval {
        local $SIG{ALRM} = sub { die "alarm\n" };
        alarm $timeout;
        print "*** reading... ";
        $line = <STDIN>;
        print "done\n";
        alarm 0;
    };

    die if $@ && $@ ne "alarm\n"; # propagate errors
    last if (!$@ && !defined($line));      # EOF

    if (!$@) {
        print "==================> line: $line";
        next;
    }
}

exit 0;

=====================================================================



-- 
Alexander L. Belikoff
Bloomberg L.P. / BFM Financial Research Ltd.
abel@vallinor4.com, abel@bfr.co.il