[clug-talk] Call a program in C and get the child PID?

Robert Lewko lewkor at telus.net
Mon Sep 19 11:09:18 PDT 2005


On September 19, 2005 10:31 am, Roy Souther wrote:
> Does anyone know how to call a child program in C and get the PID?
>
> The system command only returns the exit code, fork copies the running
> program and the many version of exec terminate the original program.
>
> I want to spawn the called program, keep it running and get the PID
> back. I want my C program to start a shell in xterm and then be able to
> go and do other things and watch for the xterm shell to be closed by the
> user.
>
> go_do("xterm &");
> ChildPid = SomeHowGetTheChildPid();
What I will give you is some theory and then an example from the top of my 
head, so take the code with a grain of salt, but it should not be too bad.  

Here goes.  What you need to do is call fork and then detect which process is 
the child and which is the parent.  How to tell the child from the parent is 
that in the parent fork will return the pid of the child and in the child 
fork will return 0.  Then to run the program that you want the child calls 
one of the exec family.

For the parent to get notified when the child exits you need to set a signal 
handler to get the SIGCHLD event.  In this event handler you will call 
waitpid to cleanup after the child has exited.  Not doing so will result in a 
"zombie" process when the parent exits.  The zombie does not really harm 
anything unless there are enough to fill your kernel process table.  When 
that happens you will not be able to create more processes, so depending on 
how many of these children are created and how long you leave your computer 
before booting you may or may not run into this.  Running out of space in the 
kernel process table is VERY BAD!!!

The following code does not implement the signal handler.  I cannot spare the 
time to look up how to do the signal handler just now.  What you need to 
lookup is how to set up a signal handler (use the sigaction function call) 
and just call waitpit(pid) in the signal handler.

What the following example is is a function that will take an argument which 
is a program on the path to run.  It will store the pid in a global and 
continue execution.  Probably you would want to set the signal handler in 
this function before the fork.

So now for some code.  This is coming from memory, so I just hope its not too 
bad.

int pid;  /* global */

void spawnchild(char* prog)
{
    if ((pid = fork()) == 0)  /* parent returns non zero */
    {
        /* this code executes in the mew child */
        execlp(proc, "arg1", "arg2", "arg3", "argn", 0);
        /* any code past this point is never executed because its replaced
           by the child */
    }
    return;
}

That is very simple.  The reason that there is no code for the parent is that 
you are going to continue processing and if you set up a signal handler then 
nothing is needed in the parent.  Hope that gets you started.

For references, try:
The Programming in the UNIX environment. Stevens.
UNIX Network Programming.  Stevens.



More information about the clug-talk mailing list