in reply to Eval leaving zombies when dying with alarm

Just install a SIGCHLD handler:
use POSIX ":sys_wait_h"; sub reaper { do { $kid = waitpid(-1, WNOHANG); } while $kid > 0; } $SIG{CHLD} = \&reaper;
There might be another way to specify this kind of SIGCHLD action, but this is basically what needs to be done.

Update: using $SIG{CHLD} = 'IGNORE'; should also do this.

Replies are listed 'Best First'.
Re^2: Eval leaving zombies when dying with alarm
by yogsothoth (Novice) on Apr 25, 2008 at 21:32 UTC
    Thanks for the reply. Maybe I am not implementing it correctly because I still have the tcpdump process hanging around. I'll play around with it some more.
      Apparently those processes are not zombies. You'll need to kill the tcpdump process when the alarm goes off, and in order to do that you'll need to know its pid.

      Actually, I think I'd use a different approach:

      my $pid = open(T, "tcpdump ...|"); eval { while (1) { $SIG{ALRM} = sub { die "time to stop" } alarm(20); my $line = <T>; # read a line from tcpdump alarm(0); last unless defined($line); # process line } }; kill 9, $pid; close(T);
      Or, you can use IO::Select:
      my $pid = open my $T, "tcpdump ...|"; my $sel = new IO::Select($T); my $buf; while ($sel->can_read($T, 20)) { read($T, $buf, 1024, length($buf)) or last; } kill 9, $pid; close($T); # $buf contains output from tcpdump
        You were right when you pointed out that they aren't actually zombies. Your approach worked perfectly and is much cleaner. I was playing around with using open, but I didn't think of grabbing the PID, that is much better than the way I was doing it. Thanks for the help.