I don't understand why the parent process continues executing even if his child process didn't terminate.
This is a.c:
if (!fork()){
execl("/bin/sh", "sh", "-c", "gnome-terminal -x ./b", (char *) 0);
}
else {
int status;
wait(&status);
if ((status & 255) == 0) printf("\nProcess regularly exited ");
printf("adios");
return 0;
}
and this is b.c:
printf("hello\n");
fflush(0);
getchar();
exit(0);
It happens that the parent process prints "process regularly exited" and "adios" when the child process hasn't terminated and it is waiting for input by getchar() ,and I don't understand why.
Finally ,how can I force the parent process to wait until the execution of b.c is completed?
Converting comments into an answer.
One key question when facing a C program that doesn't work as you expect when executing another is 'what happens in the shell'. For this question, that translates to:
When you run sh -c "gnome-terminal …"
from the command line, how long does it take before you get the prompt back?
It is instantly.
So — surprise, surprise — the same thing happens when you run it from your C code. The shell of the sh -c …
exits promptly, so your parent process spots its death and exits. I think your second program is run as a grandchild or great-grandchild of the process you fork off. You have sh
, which runs gnome-terminal
, which probably forks and the parent exits while the child goes on to manage the terminal and fork a shell that runs your second command (or maybe doesn't use a shell and simply executes your second command). A process can only wait for its direct children to die; it can't wait for its children's children or more distant descendants.
Now if I add
while(1){}
at the end ofa.c
beforereturn 0
, and at the end ofb.c
beforeexit(0)
, thetop
command indicates that I have 4 processes: 2 ofa.c
and 2 ofb.c
. Isn't it strange?
There are multiple things that could be going on. It could be leftover processes from previous runs. You'd need to look at the process trees to know if those processes are related and how they're related.
Thank you they were simply leftover processes.
Finally, how can I force the parent process to wait until the execution of
b.c
is completed?
Succinctly, you can't make A wait for B to finish. You'd need a way for A to know which process is the B that it should wait for. It can't wait directly for it because B is not its own child, so you'd probably end up doing some polling operation to see if B is still around. That might be testing with kill()
and signal 0; on Linux, you might be able to play with iNotify on the /proc
file system (and avoid polling).