Heres a breakdown of my code.
I have a program that forks a child (and registers the child's pid in a file) and then does its own thing. The child becomes any program the programmer has dignified with argv. When the child is finished executing, it sends a signal (using SIGUSR1) back to the parent processes so the parent knows to remove the child from the file. The parent should stop a second, acknowledge the deleted entry by updating its table, and continue where it left off.
pid = fork();
switch(pid){
case -1:{
exit(1);
}
case 0 :{
(*table[numP-1]).pid = getpid(); //Global that stores pids
add(); //saves table into a text file
freeT(table); //Frees table
execv(argv[3], &argv[4]); //Executes new program with argv
printf("finished execution\n");
del(getpid()); //Erases pid from file
refreshReq(); //Sends SIGUSR1 to parent
return 0;
}
default:{
... //Does its own thing
}
}
The problem is that the after execv successfully starts and finishes (A printf statement before the return 0 lets me know), I do not see the rest of the commands in the switch statement being executed. I am wondering if the execv has like a ^C command in it which kills the child when it finishes and thus never finishes the rest of the commands. I looked into the man pages but did not find anything useful on the subject.
Thanks!
execv replaces the current process with a new one. In order to spawn a new process, you can use e.g. system()
, popen()
, or a combination of fork()
and exec()
execv
replaces the currently executing program with a different one. It doesn't restore the old program once that new program is done, hence it's documented "on success, execv does not return".
So, you should see your message "finished execution" if and only if execv
fails.
Other people have already explained what execv
and similar functions do, and why the next line of code is never executed. The logical next question is, so how should the parent detect that the child is done?
In the simple cases where the parent should do absolutely nothing while the child is running, just use system
instead of fork
and exec
.
Or if the parent will do something else before the child exits, these are the key points:
- When the child exits, the parent will get
SIGCHLD
. The default handler for SIGCHLD
is ignore. If you want to catch that signal, install a handler before calling fork
.
- After a child has exited, the parent should call
waitpid
to clean up the child and find out what its exit status was.
- The parent can also call
wait
or waitpid
in a blocking mode to wait until a child exits.
- The parent can also call
waitpid
in a non-blocking mode to find out whether the child has exited yet.
What did you expect to happen? This is what execv
does. Please read the documentation which says:
The exec() family of functions replaces the current process image with a new process image.
Perhaps you were after system
or something, to ask the environment to spawn a new process in addition to the current one. Or.. isn't that what you already achieved through fork
? It's hard to see what you want to accomplish here.