Cocoa – Ensure a subprocess is dead in Cocoa

cocoanstask

I'm writing an application that kicks off a subprocess running a simple web server. I am using NSTask and communicating with it with pipes, and everything seems more or less fine. However, if my program crashes, the subprocess is left alive and the next time I launch the app there is a conflict between the old subprocess and the new one. Is there any way to ensure that subprocesses die when the owning app dies?

Best Answer

None of the above works… Not even launchd in all it's crappily-documented-complexity has a way to handle this common scenario. I dunno why Apple doesn't just make a "mothership-approved" way to run background processes, but whatever.. my solution is…

  1. Launch a shell script via NSTask and pass it any variables you need. Also pass in your parent process' PID via int masterPID = [[NSProcessInfo processInfo] processIdentifier]; etc. Read these in your script via $1, $2, etc.

  2. In turn, launch your subprocesses from inside the script..

  3. Monitor both the subprocess AND your parent process within the script.

This serves a dual purpose.. it enables you to "keep an eye on the kids..", and in the sad event of parentcide (or horrible car accident) - kill-off the zombie orphans. Then, you pull the trigger on yourself (you being the shell script) and your process table will be clean.. as if you never existed. No blocked ports, no conflicts on relaunch, no app-store rejections. Lemme know if this helps!

Update: I made a Xcode template / daemon / project / whatever that does the trick. Check it out.. mralexgray / Infanticide.