Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

IO::Select and alarm()

by Maddingue (Sexton)
on Mar 19, 2009 at 14:40 UTC ( #751738=perlquestion: print w/replies, xml ) Need Help??
Maddingue has asked for the wisdom of the Perl Monks concerning the following question:

Hello fellow monks, I am writing a program built around a loop on a IO::Select object. So far so good. Now I need to throw in a task that must be regularly executed. So I thought setting it as a SIGALRM handler. Sounds simple:
use strict; use warnings; use IO::Select; use IO::Socket; use POSIX qw< :signal_h >; my $port = 6681; my $listen = IO::Socket::INET->new( Proto => "tcp", LocalPort => $port, Listen => 10, Timeout => 10, ) or die "Can't bind socket to port $port: $!"; my $select = IO::Select->new($listen); print STDERR "listing on port $port\n"; my $alarm_handler = sub { print STDERR "! alarm handler\n"; alarm(2); }; my $sigset = POSIX::SigSet->new(SIGALRM); my $sa_alarm = POSIX::SigAction->new($alarm_handler, $sigset, SA_RESTA +RT); sigaction(SIGALRM, $sa_alarm); #$SIG{ALRM} = $alarm_handler; alarm(2); while (my @ready = $select->can_read) { for my $fh (@ready) { if ($fh == $listen) { my $sock = $listen->accept; $select->add($sock); } else { # ... } } }
Execpt that when running this program, it outputs:
$ perl listing on port 6681 ! alarm handler
and exits after the first SIGALRM. What is the obvious thing I'm missing to make the while restart (apart from nesting it in a while(1) { .. } loop)?

Replies are listed 'Best First'.
Re: IO::Select and alarm()
by ikegami (Pope) on Mar 19, 2009 at 14:48 UTC
    use Errno qw( EINTR ); for (;;) { my @ready = $select->can_read() or do { next if $! == EINTR; last; }; for my $fh (@ready) { ... } }


    Note that die("select: $!\n"); would be more appropriate than last, but I preserved the behaviour of the OP.

      Thank you, it works.

      Now I feel stupid because I should have remembered this :)

        There's a difference between can_read and select. can_read returns immediately when the object has no file handles, but I assumed it sleeps indefinitely like select in that situation.

        That means there's a bug in my earlier version. The OP's code is equivalent to

        use Errno qw( EINTR ); while ($select->count()) { my @ready = $select->can_read() or do { next if $! == EINTR; last; # Should be die("select: $!\n"); }; for my $fh (@ready) { ... } }

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://751738]
Approved by moritz
Front-paged by grinder
[Corion]: But yes, "who started this process" is interesting information :)
[tye]: no, I really believe that "login user" was added as a fundamental bit of info about each process in order to enhance the usefulness of auditing
[Corion]: Ah - if that information is saved in a file, then you could theoretically spam that file and confuse getlogin(). So, don't use it for authentication :)
[tye]: that is what getlogin() certainly *used* to do. I don't believe that is what it certainly should do.
[davido]: /var/run/utmp is 664 i think.
[tye]: Note that my "man getlogin" says that it uses stdin when it should use /dev/tty (calling a glibc bug). But that does not appear to be the case when I test it. But maybe Perl's getlogin() is not using glibc's getlogin().
[oiskuu]: well, run a strace and see what the getlogin does for you.... As I said. SELinux probably has those security labels. But not regular linux.
[tye]: for example, read https://unix. questions/146138/ loginuid-should-be -allowed-to-change -or-not-mutable-or -not
[tye]: I'm not using SELinux and it certainly appears to disagree with you. shrug
[tye]: Since you brought up /proc, oiskuu, I didn't see you respond to my suggestion of 'loginuid'. Does your /proc not have such?

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (6)
As of 2017-06-23 19:46 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (554 votes). Check out past polls.