문제

My pipe (filehandle, socket) breaks (sometimes). I can reproduce it with the following code:

my $counter = 5;
alarm(1);

open(FH,"while(sleep 2); do date; done |") or die $!;
while (<FH>) { print; }
close(FH);

BEGIN {
    $SIG{ALRM} = sub { 
        print "alarm!\n"; 
        exit if --$counter == 0;
        alarm(1);
    };
}

Which will produce:

alarm!
alarm!
Thu Feb  7 11:46:29 EST 2013
alarm!
alarm!
alarm!

If I strace this process, I see that the spawned shell gets a SIGPIPE. However, the Perl process happily continues. How do I fix this?

도움이 되었습니까?

해결책

The problem is that <FH> is returning false because of an interrupted system call. I am not sure if this is the idiomatic way to handle this in perl (and would love to see a better answer), but the following seems to work:

my $counter = 5;
alarm 1;

open my $fh, '-|', 'while(sleep 2); do date; done' or die $!;
loop:
while (<$fh>) { print; }
goto loop if $!{EINTR};
close $fh;

BEGIN {
    $SIG{ALRM} = sub { 
        print "alarm!\n"; 
        alarm 1;
        exit if --$counter <= 0;
    };
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top