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 offork()
andexec()
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.What did you expect to happen? This is what
execv
does. Please read the documentation which says: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 throughfork
? It's hard to see what you want to accomplish here.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 offork
andexec
.Or if the parent will do something else before the child exits, these are the key points:
SIGCHLD
. The default handler forSIGCHLD
is ignore. If you want to catch that signal, install a handler before callingfork
.waitpid
to clean up the child and find out what its exit status was.wait
orwaitpid
in a blocking mode to wait until a child exits.waitpid
in a non-blocking mode to find out whether the child has exited yet.