Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!uunet!mcsun!unido!mikros!mwtech!martin From: martin@mwtech.UUCP (Martin Weitzel) Newsgroups: comp.unix.questions Subject: Re: Killing a background process from a C program Message-ID: <857@mwtech.UUCP> Date: 24 Jul 90 23:10:16 GMT References: <1990Jul19.151728.17448@ncs.dnd.ca> <1990Jul19.201116.13696@Neon.Stanford.EDU> Reply-To: martin@mwtech.UUCP (Martin Weitzel) Organization: MIKROS Systemware, Darmstadt/W-Germany Lines: 54 In article <1990Jul19.201116.13696@Neon.Stanford.EDU> dkeisen@Gang-of-Four.Stanford.EDU (Dave Eisen) writes: >In article <1990Jul19.151728.17448@ncs.dnd.ca> marwood@ncs.dnd.ca (Gordon Marwood) writes: >> >>What I would like to do is start a background process at one point in the >>C program, and at a later time kill it. Currently I am invoking the >>background process with system("background_process &");, but none of the >>texts that I have available help me to proceed any further. >> > >System is not a powerful enough tool for this, it is designed for only >the simplest of process control situations. You'll have to fork and >exec the new process yourself. [...] Though the solution sketched thereafter by Dave Eisen is surely correct, it's not the only way to go. In fact, it often goes unnoticed (because it's not obvious) that you can start background-processes without fork/exec and still wait for them at any time later by using `popen'. At first glance the purpose of `popen' seems different (communicate thru a pipeline to stdin or stdout of a program), but if the background process doesn't use stdin/stdout - or you redirect them to files - `popen' can safely be used to invoke background processes. If you want to wait for such a process later, just use the appropriate `pclose'. If you need to kill one and must have its PID, you can either go the non-portable way and try to figure out how and where `popen' stores the relevant information - or use this: FILE *bpd; int t, pid; bpd = popen("echo $$; exec backgroundprocess" , "r"); /* %% */ ... check for errors /* assert(bpd != (FILE *)0) */ ... t = fscanf(bpd, "%d", &pid); ... again check for errors /* assert(t == 1) */ ... ... let background process run and do its work ... ... later you may stop it gracefully ... kill(pid, SIGTERM); ... or with brute force ... kill(pid, SIGKILL); ... and don't forget to cleanup zombies from process table ... pclose(bpd); >For more details [...] pick up >a copy of Marc Rochkind's Advanced Unix Programming. (BTW -- even though >it is a UNIX book and not a C book, I think it should be mentioned >in the Frequently Asked Questions posting as an excellent reference for >C programming under UNIX.) My opinion too. %%: If these lines shall go into a later SETUID-ed program, you must pay special attention to assure that the "right" program is started here. But as this is generally true for `system', `popen', and partially for `execv' too, I'll not go into the security details here. -- Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83