2013-02-07 2 views
2

내 파이프 (파일 핸들, 소켓)가 깨집니다 (간혹). 나는 다음과 같은 코드로 재현 할 수 있습니다 :Perl : SIGALRM이 파이프를 닫지 않게하는 방법?

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); 
    }; 
} 

생산합니다 어느 :이 과정을 strace의 경우

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

, 나는 양산 쉘이 SIGPIPE를 얻을 것을 알 수있다. 그러나 Perl 프로세스는 계속 행복하게 진행됩니다. 이 문제를 어떻게 해결할 수 있습니까?

+0

문제가 무엇입니까? ALRM에 대한 처리기에서 exit를 호출하므로 perl은 종료하고 파일 설명자를 닫습니다. 서브 쉘이 닫힌 파일 핸들에 쓸 때 SIGPIPE를 얻습니다. 서브 쉘이 SIGPIPE를 무시하고 쓰기가 실패하여 영원히 계속하기를 원합니 까? –

+0

'exit'를 호출하면 펄 프로세스가 행복하게 계속됩니까 ?? – mob

답변

2

시스템 호출이 중단되어 <FH>이 false를 반환하는 것이 문제입니다. 나는이 펄이 처리하는 (그리고 더 나은 대답을보고 싶어요) 숙어 방법입니다 있는지 확실하지 않습니다,하지만 다음은 작동하는 것 같다 :

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; 
    }; 
} 
+0

나는 "관용적"인 것에서도 모른다. 그러나 이것도 내가 일반적으로 한 것이다. – darch