DEV Community

Discussion on: GNU timeout annoyed me so I replaced it; or an extremely simple introduction to fork() and signal handling in perl

Collapse
 
sbakker profile image
Steven Bakker • Edited

Looks like a alarm() and group kill do the same job. Only requires POSIX.

#!/usr/bin/perl

use 5.014;
use warnings;
use POSIX qw( setpgid );

my $USAGE = "usage: $0 nsecs command ...\n";

@ARGV >= 2 or die $USAGE;
my ($timeout, @command) = @ARGV;
$timeout =~ /^\d+$/ or die $USAGE;

# Create new process group with ourselves as the group leader.
setpgid($$, 0) or die "cannot setpgid(): $!\n";

# Catch an ALRM signal by sending the TERM signal to the group.
$SIG{ALRM} = sub {
    warn "TIMEOUT\n";
    kill 'TERM' => -$$;
};

# Any group kill will also hit us, so exit nicely.
$SIG{TERM} = sub { exit(128 + 14) };

alarm($timeout); # Arm the timer.
system { $command[0] } @command; # Run the command.
alarm(0); # Disarm the timer.
exit $?; # Exit with the child status.
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ap profile image
Aristotle Pagaltzis

FWIW, use strict is redundant given your use 5.014. (This applies to use 5.012 and up.)

Thread Thread
 
sbakker profile image
Steven Bakker

Fixed, including the things you mention below. Thanks.

Collapse
 
ap profile image
Aristotle Pagaltzis
@ARGV == 2 or die $USAGE;

This is needlessly restrictive. It should be >= instead of ==. That way you can avoid running the given command through the shell.

system @command;

It may be useful to use system { $command[0] } @command here instead, which will ensure the command is never run under shell. This loses a bit of convenience if the user did want to run the command under shell, but prepending sh -c ... to the arguments is no big deal and this keeps the program from containing a hidden “oops, you got shell when you didn’t mean to” trap.

But this is more subjective than the other change.

Thread Thread
 
sbakker profile image
Steven Bakker

Good suggestions, thanks. I quickly threw this together to test the signal mechanism, didn't pay attention to the arguments that much.