T
Todd Pytel
Hi all,
An infrequent perl coder here, having some issues with signal handling.
I'm not understanding something about how forking works with signals, I
think. The script is supposed to loop, running tcpdump until it exits
(after a certain number of packets are captured), rotating the dump output
and analyzing the output with tcpstat. Since the tcpdump can be rather
lengthy, I'd like to catch TERM signals and have the output analyzed so as
not to lose data. Here's some of what I've come up with - the use of pid
files is rather ghetto, I think, so suggestions are welcome:
$SIG{'TERM'} = \&term_handler;
sub main {
while ( 1 ) {
( $stop ) && exit;
defined (my $pid = fork) or die "Cannot fork: $!";
unless ($pid) {
exec "tcpdump -c $packet_count -i $interface -w $output > /dev/null 2>&1";
}
open PIDFILE, "> $dumppid";
print PIDFILE "$pid\n";
close PIDFILE;
waitpid($pid, 0);
unlink $dumppid;
&rotate;
&analyze; # Should fork this, too - don't want to wait on analysis
}
}
sub term_handler {
print "Running term_handler...\n";
$stop = 1;
if ( -e $dumppid ) {
open PIDFILE, "$dumppid";
while (<PIDFILE>) {
chomp;
kill 15, $_;
}
close PIDFILE;
}
}
The problem is that the signal never gets caught, so the tcpdump keeps
going, and the cleanup at the end of main never occurs. From what I've
seen searching, this has something to do with the parent waiting on the
child process, but I'm not experienced enough to see exactly what the
problem is. Is there a solution or alternate approach that I can use here?
Thanks,
Todd Pytel
An infrequent perl coder here, having some issues with signal handling.
I'm not understanding something about how forking works with signals, I
think. The script is supposed to loop, running tcpdump until it exits
(after a certain number of packets are captured), rotating the dump output
and analyzing the output with tcpstat. Since the tcpdump can be rather
lengthy, I'd like to catch TERM signals and have the output analyzed so as
not to lose data. Here's some of what I've come up with - the use of pid
files is rather ghetto, I think, so suggestions are welcome:
$SIG{'TERM'} = \&term_handler;
sub main {
while ( 1 ) {
( $stop ) && exit;
defined (my $pid = fork) or die "Cannot fork: $!";
unless ($pid) {
exec "tcpdump -c $packet_count -i $interface -w $output > /dev/null 2>&1";
}
open PIDFILE, "> $dumppid";
print PIDFILE "$pid\n";
close PIDFILE;
waitpid($pid, 0);
unlink $dumppid;
&rotate;
&analyze; # Should fork this, too - don't want to wait on analysis
}
}
sub term_handler {
print "Running term_handler...\n";
$stop = 1;
if ( -e $dumppid ) {
open PIDFILE, "$dumppid";
while (<PIDFILE>) {
chomp;
kill 15, $_;
}
close PIDFILE;
}
}
The problem is that the signal never gets caught, so the tcpdump keeps
going, and the cleanup at the end of main never occurs. From what I've
seen searching, this has something to do with the parent waiting on the
child process, but I'm not experienced enough to see exactly what the
problem is. Is there a solution or alternate approach that I can use here?
Thanks,
Todd Pytel