Starting up another process from within a C program
Doctor Software
jmb at patton.wpd.sgi.com
Thu Nov 8 02:58:55 AEST 1990
In article <1990Nov5.124751.14923 at jarvis.csri.toronto.edu>,
corkum at csri.toronto.edu (Brent Thomas Corkum) writes:
> What I want to do is start up and run another program in the background from
> within a C program. I want to continue to run the program that invokes the
> other program ... Now, I can successfully do this using
> the system function with the following syntax:
>
> system("analysis test.dat &"); /* test.dat is the data file */
>
> What I want to know is whether this is the best way of doing it and what
> other options are there. I looked at exec but this seems to kill the parent
> process.
>
Exec in all it's forms does NOT kill the parent process - the only way
to do that is to signal(2) the parent or for it to call exit(2). Your
mistake is probably in not calling fork(2) before calling exec(2) - as
it says in the man page, exec(2) "overlays the current process image
with a new image taken from the named file". Thus, it probably seemed
like your parent exited - but you never had one!
Rather than go into the arcane incantation needed to do the fork/exec
sequence, I prefer to use the popen()/pclose() library routines. popen()
does what system() does, except it returns a FILE * (a standard IO file
descriptor) which is attached to the process. Thus allows you to send
data to the program, or to get data back. pclose() can be used to pick
up the exit status of the process, and to kill it if you want.
However, if you need to both write to the child and read from it,
popen() won't do it. In that case, you need to do the classic fork/exec
sequence:
int readpipe[2];
int writepipe[2];
pipe(readpipe);
pipe(writepipe);
if (fork() == 0) {
close(readpipe[1]);
close(0);
dup(readpipe[0]);
close(writepipe[0]);
close(1);
dup(writepipe[1]);
close(2);
dup(writepipe[1]);
execl("/bin/myprog", "myprog", arg1, arg2, 0);
}
close(readpipe[0]);
close(writepipe[1]);
Now in this sequence I left out all the error checking a good programmer
would do, but this is the core of what needs to be done. Essentially,
after this sequence, data written to readpipe[1] will appear as standard
input to the child, and standard output and standard error in the child
will appear on the writepipe[0] descriptor. Examination of the man pages
for pipe(2) and dup(2) is left as an excersize for the reader.
Of course, you probably want to save the process ID returned by fork()
so you can manipulate the process at some later time (e.g., kill(2) it
or wait(2) for it). If you get really creative, you can catch SIGCHLD
(signal(2)) so you get an interrupt if the child terminates unexpectedly.
Now you understand why I like to use popen()/pclose().
>
> Also, I want to have the analysis program ring a bell when it's done. I
> looked at the man pages for setbell and ringbell but I can't seem to get
> the program to compile, I get the old Undefined function error. So how
> do I use these? Or is there another way to ring the keyboard bell from
> within a C program.
>
Basically, your parent program should ring the bell when the child
terminates. It can find out when the child is done as I described above
(i.e., wait(2) or SIGCHLD) and when that happens, ring the bell.
> Brent
> corkum at boulder.civ.toronto.edu
-- Jim Barton
Silicon Graphics Computer Systems
jmb at sgi.com
More information about the Comp.sys.sgi
mailing list