http://qs1969.pair.com?node_id=121732


in reply to Logging out

Update

Well, the following snippet of code is pretty ugly, but it seems to work. It is executed by the server program in response to a command from the client via SOAP.

my @ps = `ps -ef`; my @pid = (split(/ +/, (grep(/login -- mrc/, @ps))[0]))[1]; my @kill; while (1) { last unless @pid = grep {$_ > 1} @pid; push @kill, @pid; my $pidlist = join('|', @pid); last unless @pid = grep(/\s+[\d]+\s+($pidlist) /, @ps); @pid = map {(split(/\s+/, $_))[1]} @pid; } kill 'TERM', @kill
What this does is get a list of all running processes, finds one named "login -- mrc", then goes through the list looking for all its children, children's children, etc. Once it's done this, it kills them all. Ugh.

Replies are listed 'Best First'.
Re: Re: Logging out
by rob_au (Abbot) on Oct 28, 2001 at 10:09 UTC
    As I'm a great proponent of implementing in Perl rather than relying on external programs, I came up with the following more generic code which is a bit cleaner in that it doesn't depend on the external execution of ps :

    sub killchd ($;$) { use Proc::ProcessTable; my $sig = ($_[1] =~ /^\-?\d+$/) ? $_[1] : 0; my $proc = Proc::ProcessTable->new; my %fields = map { $_ => 1 } $proc->fields; return undef unless exists $fields{'ppid'}; foreach (@{$proc->table}) { kill $sig, $_->pid if ($_->ppid == $_[0]); }; kill $sig, $_[0]; };

    This subroutine takes two arguments, the parent process ID and the numeric signal to pass to the processes (which would be 9 if you wanted to issue a -TERM). Using Proc::Process you could find the process ID of the process login -- mrc with something similar to the following :

    my $proc = Proc::ProcessTable->new; my @ps = map { $_->pid if ($_->cmndline =~ /login -- mrc/) } @{$proc-> +table}; &killchd($_, 9) foreach @ps;

     

    Ooohhh, Rob no beer function well without!

      Yes, I like that much better. Thanks!