问题
I'm trying a small unit-testing here. But the program doesn't work as I expected.
char *args[2];
args[0] = (char*)"/usr/bin/firefox";
args[1] = NULL;
pid = fork();
printf("forked and my pid is %d\n",pid);
//check for errors
if (pid<0){
printf("Error: invoking fork to start ss has failed, Exiting\n ");
exit(1);
}
//the child process runs firefox
if (pid==0){
if (execv(args[0],args)<0){
perror("Error: running s with execvp has failed, Exiting\n");
}
printf("IVE BEEN KILLED\n");
}
//dad is here
printf("DAD IS GOING TO KILL U\n");
if (pid>0){
sleep(3);
kill(get_pidof(string("firefox")),SIGUSR1);
}
Now, I would expect the program to run as follow: 1.the child runs firefox (which it does) 2.the dad prints DAD IS GOING TO KILL U (so far so good) 3.the firefox would open for 3 seconds and then close (does that too) 4.the child process would finish running execv and print "IVE BEEN KILLED". This doesn't happen.
My aim is to know that the program which execv ran has finished by raising a few flags right after execv continues running (where the ive been killed printf is). I have a code of a few thousand lines and don't want to use other methods, unless necessary.
Thanks
回答1:
execv()
replaces the current process with a new process. When firefox is started via execv()
the printf("IVE BEEN KILLED\n")
essentially no longer exists in the process and will never be executed (see man execv). It would be possible for the parent process to wait for the child, firefox, to exit by using wait() or to be alerted to the death of the child process via a signal (e.g. signal(SIGCHLD, child_exit_handler)
).
回答2:
You've killed the child and it doesn't catch the signal so it just dies. At least it would if exec returned, but it doesn't. So you'd only execute the print if the exec failed.
If you want to know if your child has finished, use the wait
call.
Note also that as your child doesn't exit, it'll then execute the parent pid's code, which could be interesting.
来源:https://stackoverflow.com/questions/13290594/fork-kill-and-execv