From the kill(2) system call's man page:
If pid is negative but not -1, sig is sent to all processes (except an unspecified set of system processes) whose process group ID is equal to the absolute value of pid and for which the process has permission to send a signal.
EDIT
(I'm asking for clarification here, but I need room and formatting that aren't available in the comment area)
So pstree would print:
startserv --- expect --- /bin/sh --- srcds_linux
And grouping the groups would be:
{startserv --- expect} --- {/bin/sh --- srcds_linux}
And from startserv
you want to kill expect
, /bin/sh
, and srcds_linux
, but killing expect
does not result in expect
killing its immediate child (much less the group that that child is the head of).
Some more suggestions
It may be that killing expect with some signal besides SIGKILL
(9) such as SIGTERM
might cause expect
to kill its child (and maybe group) for you before terminating itself, but you may have already tried that.
Baring that you could try looking through /proc/*/stat
to build a process tree, and find your expect
process (you already know its pid), and then kill it and all of its children. This isn't perfect since it's not atomic (/bin/sh could fork some more children or something), but if you want to try to catch that as well you could send all processes in this sub-tree SIGSTOP
as realize that they are under the expect
sub-tree to stabilize that tree. Then send them all a stronger kill possibly followed by a SIGCONT
.
A more automatic way to accomplish this would be to have startserv
create a psudoterminal to run expect
(and its descendants) on and then close the controlling side of the psudoterminal and hope that all of those programs die on SIGHUP
.