marwood@ncs.dnd.ca (Gordon Marwood) (07/19/90)
I am in the process of converting a Bourne shell script to C, and I am having trouble finding out how to identify and kill background processes. With the Bourne Shell approach this was simple, using $!. 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. Any assistance would be appreciated. Gordon Marwood Internet: marwood@ncs.dnd.ca
dkeisen@Gang-of-Four.Stanford.EDU (Dave Eisen) (07/20/90)
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. Fork will create a new process and return the pid of that process, at some later point use kill (pid, signal_number) to kill it. For more details, drop me a note or (better still) 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.) Followups redirected to comp.unix.questions. -- Dave Eisen Home: (415) 323-9757 dkeisen@Gang-of-Four.Stanford.EDU Office: (415) 967-5644 1447 N. Shoreline Blvd. Mountain View, CA 94043
larrym@pi19.pnfi.forestry.ca (Larry Marshall) (07/20/90)
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. The latest Computer Language (July) has an article on manipulating Unix processes in C. It discusses the monitoring of PIDs and includes code for terminating those processes. Larry Marshall Petawawa National Forestry Institute
truong@wk35..nas.nasa.gov (Tuong C. Truong) (07/24/90)
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. >> > Just off the top of my head, but you may want to try something like : set PID = `background_process&` at this point PID will keep track of the process ID of the background process. later when you want to kill it, you may use something like: kill -9 $PID I have not tried this, but hope it works. ------------------------ Signature Under Construction.
martin@mwtech.UUCP (Martin Weitzel) (07/25/90)
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
george@hls0.hls.oz (George Turczynski) (07/25/90)
In article <7459@amelia.nas.nasa.gov>, truong@wk35..nas.nasa.gov (Tuong C. Truong) writes: > Just off the top of my head, but you may want to try something like : > > set PID = `background_process&` > > at this point PID will keep track of the process ID of the background process. > later when you want to kill it, you may use something like: > > kill -9 $PID > > I have not tried this, but hope it works. I have not tried this either, but I know it won't work. That simply isn't `C'. The initial poster was writing in `C', and might get very confused trying to use your solution :-) Anyway, try something like this: #include<stdio.h> #include<signal.h> #define FOO_OK 0 #define FOO_BAD_EXEC 1 #define FOO_BAD_FORK 2 #define FOO_BAD_KILL 3 int foo(myname) char *myname; /* Perhaps equal to *argv[0]. */ { int pid; /* ... code ... */ switch( pid= fork() ) { case 0: /* execve() or execl etc. your child here. */ /* * eg. * * execl("/bin/cat","cat","/etc/passwd",(char *)0); * */ /* Should only get to here if exec?() fails. */ return FOO_BAD_EXEC; case -1: /* fork() failed. */ return FOO_BAD_FORK; } /* ... Parent code ... */ if( kill(pid,SIGTERM) < 0 ) return FOO_BAD_KILL; /* ... rest of code ... */ return FOO_OK; } I humbly apologise for any typos in the above. If anyone wants to flame this, do it in aus.flame >please<. Note: kill() _will_ fail if the child has exited before kill() is called. Note: the use of "kill -9" is in VERY POOR TASTE with respect to unix. "SIGTERM" (#15) is the software termination signal, so use it. I hope this is of some benefit to the original poster, and to anyone else watching. Have a nice day... George P. J. Turczynski | ACSnet: george@highland.oz System Administrator | Phone: 61 48 683490 System Programmer | Fax: 61 48 683474 Logic Designer. |---------------------- Highland Logic Pty. Ltd. | I can't speak for the Suite 1, 348-354 Argyle Street | company, I can barely Moss Vale. NSW. 2577 Australia | speak for myself...
venkat@matrix.UUCP (D Venkatrangan) (07/27/90)
In article <1990Jul19.151728.17448@ncs.dnd.ca> marwood@ncs.dnd.ca (Gordon Marwood) writes: >I am in the process of converting a Bourne shell script to C, and I am >having trouble finding out how to identify and kill background >processes. With the Bourne Shell approach this was simple, using $!. > >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. > >Any assistance would be appreciated. > Instead of system(), try using vfork() followed by execlp(). In foreground program, do something like: if ((child_pid = vfork()) == -1) perror("vfork failed"); if (child_pid == 0) { execlp(execfile, execfile, arg1, arg2, ..., (char *)0); /* should not return */ perror("exec failed"); } /* parent */ /* if we get killed... */ (void)signal(SIGINT, kill_child); /* call kill_child() to send a user defined signal to child. */ /* or just call kill(child_pid, SIGUSR1); */ void kill_child(sigval) int sigval; { if (sigval == SIGINT) kill(child_pid, SIGUSR1); } In child, during initialization do: (void)signal(SIGUSR1, childsighandler); and define: void childsighandler(sigval) int sigval; { if (sigval == SIGUSR1) { /* the parent is sending something */ cleanup(); exit(); } }
mcdonald@aries.scs.uiuc.edu (Doug McDonald) (07/27/90)
In article <159@matrix.UUCP> you write: >In article <1990Jul19.151728.17448@ncs.dnd.ca> marwood@ncs.dnd.ca (Gordon Marwood) writes: >>I am in the process of converting a Bourne shell script to C, and I am >>having trouble finding out how to identify and kill background >>processes. With the Bourne Shell approach this was simple, using $!. >> PPPPP L EEEEEEE A SSSS EEEEEEE P P L E A A S S E P P L E A A S S E P P L E A A S E PPPPP L EEEE AAAAAAAAA SSSS EEEE P L E A A S E P L E A A S S E P L E A A S S E P LLLLLLL EEEEEEE A A SSSS EEEEEEE Please, keep discussion relating to operating systems OUT of comp.lang.c!! Send them to the correct OS-specific getto!!! In this case, comp.unix.questions. Doug McDonald