Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I've got a script which launches a program which needs
to be timed: i.e. after a specified amount of time
the launched program should be killed.
BTW: I'm running on Linux and Solaris (would eventually
like to do the same on Windoze, but I know its a bigger
problem there)

Here's the code:
use POSIX; my $pgrp; FORKTAIL:{ if($pidxt=fork){ #parent stuff print "First: ID is $pidxt\n"; print "Process ID of this script is: $$\n"; $pgrp = getpgrp $pidxt; }elsif (defined $pidxt){ #child stuff #$pgrp = getpgrp $pidxt; print "group id is: $pgrp\n"; print "Second: ID is: $pidxt\n"; #`xterm -sb -ls -vb -e tail -f $0`; `xterm -sb -ls -vb `; POSIX::exit(0); undef $pidxt; }else { die "Can't fork!\n"} } eval{ local $SIG{ALRM} = sub { print "id in kill is: $pidxt\n"; print "grp id is: $pgrp\n"; kill &POSIX::SIGTERM, $pgrp; waitpid($pidxt,0); die "alarm\n" }; alarm 15; waitpid($pidxt,0); alarm 0; };
It launches an xterm and after a time I'd like the xterm
to be killed (not the real application, this is just
to test the concept). What happens is that the main
program exits after the alotted time, but the xterm is
not killed.

Any ideas? Thanks. Oysterman

Replies are listed 'Best First'.
Re: How to kill an external program
by Fastolfe (Vicar) on Sep 07, 2000 at 21:23 UTC
    Something like this works for me. I'm not doing any process clean-up; this is mainly so you can see how I'm doing it:
    use POSIX qw/setsid/; $pid = fork(); if (!$pid) { setsid; # set our pgid to $$ system("sleep 30"); # just an example, put your xterm here } elsif (defined($pid)) { $SIG{ALRM} = sub { kill 'TERM', -$pid }; alarm 3; # .. do some stuff that will take longer than 3 seconds }
    This will kill the child process and the sleep (whatever you put in the system call) after 3 seconds. The negative $pid on Solaris at least kills the process group referenced by $pid. Since we called setsid() earlier, that will kill the Perl child and whatever else that child spawned. You can trap $SIG{TERM} in the child if you want to catch it and do your own cleanup in Perl before exiting, though the sleep in this case will be killed regardless of this trap, since it receives the signal independently.
Re: How to kill an external program
by kilinrax (Deacon) on Sep 07, 2000 at 21:21 UTC
    Not sure quite what you mean, but would the Proc::Simple module be of use?
    $xterm = Proc::Simple->new(); $xterm->start("xterm -sb -ls -vb"); ... $xterm->kill();