Bug in Perl script

Mark Martinec Mark.Martinec+freebsd at ijs.si
Fri Dec 9 14:21:03 UTC 2011


Alexander,

> I have a script that runs command tail with open descriptor.
> After 30 seconds, I close descriptor.  But descriptor not closed.
> When script is closed tail is present in ps aux.
> 
> $log_file = path_to_log;
> eval {
>     local $SIG{ALRM} = sub { die; };
>     alarm (30);
>     open (LOG, "tail -F $log_file|") || die "Сan`t open logfile
> \"$log_file\"";
>     while (<LOG>) {
>         ***
>     }
>     alarm (0);
> };
> close (LOG);
> print ("Ok\n");
> exit(0);
> 
> This code is good working in FreeBSD 8.2, but in FreeBSD 9.0 not working.

I don't see any difference in this respect between 8.2 and 9.0.

Even in 8.2 the spawned tail process stays alive until the moment
when it tries to write its next line to a pipe - only then it aborts
with 'Broken pipe'. On a busy log file this happens soon, on an
idling log file this may take forever.

You should abort the forked process when you no longer need it:

my $log_file = '/var/log/mail.log';
my $pid;
eval {
  local $SIG{ALRM} = sub { die "Time is up" };
  alarm(10);
  $pid = open(LOG, "tail -F $log_file|");
  $pid or die "Can't open logfile \"$log_file\": $!";
  while (<LOG>) {
    print "HERE: $_";
  }
  alarm (0);
  1;
} or do {
  alarm (0);
  print "Bail out: $@";
};
if ($pid) {
  print "Terminating process [$pid]\n";
  kill('TERM',$pid);
}
close(LOG);
print "Ok\n";


  Mark


More information about the freebsd-current mailing list