#/usr/bin/perl

# Usage: zap [-signal] pattern

# Configuration parameters.

$sig = 'TERM';

$BSD = -f '/vmunix';
$pscmd = $BSD ? "ps -auxww" : "ps -ef";

open(TTYIN, "</dev/tty") || die "can't read /dev/tty: $!";
open(TTYOUT, ">/dev/tty") || die "can't write /dev/tty: $!";
select(TTYOUT);
$| = 1;
select(STDOUT);
$SIG{'INT'} = 'cleanup';

if ($#ARGV >= $[ && $ARGV[0] =~ /^-/) {
    if ($ARGV[0] =~ /-(\w+)$/) {
	$sig = $1;
    } else {
	print STDERR "$0: illegal argument $ARGV[0] ignored\n";
    }
    shift;
}

if ($BSD) {
    system "stty cbreak </dev/tty >/dev/tty 2>&1";
}
else {
    system "stty", 'cbreak',
    system "stty", 'eol', '^A';
}

open(PS, "$pscmd|") || die "can't run $pscmd: $!";
$title = <PS>;
print TTYOUT $title;

# Catch any errors with eval.  A bad pattern, for instance.

eval <<'EOF';
while ($cand = <PS>) {
    chop($cand);
    ($user, $pid) = split(' ', $cand);
    next if $pid == $$;
    $found = !@ARGV;
    foreach $pat (@ARGV) {
	$found = 1 if $cand =~ $pat;
    }
    next if (!$found);
    print TTYOUT "$cand? ";
    read(TTYIN, $ans, 1);
    print TTYOUT "\n" if ($ans ne "\n");
    if ($ans =~ /^y/i) { kill $sig, $pid; }
    if ($ans =~ /^q/i) { last; }
}
EOF
&cleanup;

sub cleanup {
    if ($BSD) {
	system "stty -cbreak </dev/tty >/dev/tty 2>&1";
    }
    else {
	system "stty", 'icanon';
	system "stty", 'eol', '^@';
    }
    print "\n";
    exit;
}