如果孩子手动获取,IO :: Socket :: accept只能工作一次

时间:2015-09-15 21:42:06

标签: perl sockets ipc

在下面的简单回显服务器中,CJNE A,#42,DUMMY DUMMY: JC IS_LESS ; jump to IS_LESS if A<42 在第二次调用时返回accept(),如果我用自己的undef处理程序收集孩子而不是让Perl执行此操作:

SIGCHLD

换句话说:

#!/opt/perl5/bin/perl

use IO::Select;
use IO::Socket;
use POSIX qw(WNOHANG);
use strict;
use warnings;

$|=1;

use constant LISTEN_PORT => 9998;

my $server = IO::Socket::INET->new (
                 Proto     => 'tcp',
                 LocalPort => LISTEN_PORT,
                 Listen    => SOMAXCONN,
                 Reuse     => 1);

(! $server) && die "Could not setup server - $!\n";
$server->autoflush(1);


sub reaper {
    while ((my $dead_child = waitpid(-1, WNOHANG)) > 0) {
        print "Reaped PID $dead_child\n";
    }
    $SIG{CHLD} = \&reaper;
};
$SIG{CHLD} = \&reaper;    ## THIS BLOWS
# $SIG{CHLD} = 'IGNORE';  ## THIS WORKS

while (my $client = $server->accept()) {
   my $childPid;
   if (! defined($childPid = fork())) {
      die "Could not fork: $!\n";
   }
   if ($childPid == 0) {
      print $client $_ while (<$client>);
      $client->shutdown(1);
      exit();
   } else {
       print "Spawned PID $childPid\n";
   }
   close($client);

}
print "bye\n";

1 个答案:

答案 0 :(得分:3)

当您的程序收到if (cell == nil)信号时,基础SIGCHLD的系统调用可能会被中断。在这种情况下,$server->accept()将返回accept()undef将设置$!

在这种情况下需要更多的防御性编程。这是一种方式:

$!{EINTR}