views:

1458

answers:

2

I know there are many questions and answers about this, but I am looking for an efficient and robust solution. I need to kill a process AND all it's child processes from within a Cocoa app. I got the process ID and what I am about to code is to execute the kill command like so

kill -- -<parent PID>

from within my app ... but that seems awfully hacky and brutal to me. Isn't there a better solution? Carbon's KillProcess()and its Process Manager friends don't seem much help unless I build a process tree representation myself. Am I missing something?

I also have some code to send the Quit Apple Event based on PID. It would be even nicer to be able to send that to each process in the tree defined by a parent process, bottom up. But that's only a nice-to-have. An answer to the first question gets the "point".

+5  A: 

You can just use killpg to terminate the process and everything in its group:

#include <signal.h>
#include <unistd.h>

/* ... */

killpg(getpgid(pid), SIGTERM);

Proper error checking should be done, of course, but you should get the gist. See the man pages kill(2) and killpg(2) for more info.

Jason Coco
Thanks for quick reply, this worked well. Small addition: the correct function to get the process group ID for a given ID is getpgid, not getpgrp. http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/getpgrp.2.html
Thomas Jung
oh, you're right about that! Sorry, getpgrp() returns the caller's process group :)
Jason Coco
Small typo in "code sample": should be killpg()
Ivan Vučica
fixed, thanks Ivan
Jason Coco
A: 

The last time I looked into this (which was a few years ago, but I don't think much has changed) the best solution I found was just to call the system kill command.

system( "ps axwww | grep -i CoreServices/Dock.app/Contents/MacOS/Dock | grep -v grep | awk '{print $1}' | xargs kill -3" );
Marc Charbonneau
You could always have used killpg(2)
Jason Coco