问题
I've recently learned how to do the whole fork/exec/wait
thing and ended up writing some code that looked like this stripped down:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
pid_t x = fork();
if (x == 0) {
execlp("sqlite3", "sqlite3");
printf("exec failed\n");
} else {
wait(NULL);
printf("Hi\n");
}
}
This works out pretty well, and actually ends up opening the sqlite3
shell, but there's one problem. If you Ctrl + C
out of the sqlite3
shell, then it also terminates the parent process and the line printf("Hi\n")
never runs.
I assumed this was because the SIGINT was being propagating to the parent process, and after looking into it further, I read that a SIGINT will terminate all processes in the same group, meaning since the parent and child share the same group they're both terminated.
I tried to fix this by doing trying to call setpgid
like so:
int main() {
pid_t x = fork();
if (x == 0) {
setpgid(getpid(), getpid()); // <-- Added in this line
execlp("sqlite3", "sqlite3");
printf("exec failed\n");
} else {
wait(NULL);
printf("Hi\n");
}
}
which ran fine, but that broke the sqlite3
prompt. Moreover Ctrl + C
still killed the parent in this case. I decided to try to narrow it down even more, and then found something weird, and got stumped. Just putting a getpid()
call into the fork will make execlp()
fail.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
pid_t x = fork();
if (x == 0) {
getpid(); // <--- just adding this in makes it fail
execlp("sqlite3", "sqlite3");
printf("exec failed\n");
} else {
wait(NULL);
printf("Hi\n");
}
}
and not even just for sqlite3
, but for simple stuff like execlp("ls", "ls")
as well (this might be unrelated to the original question though).
I'm in a bit over my head and I was wondering if anyone could point me in the right direction. I'm not quite sure what to do from here.
- I'm on OSX 10.11, and am compiling with clang.
clang --version
: Apple LLVM version 8.0.0 (clang-800.0.42.1)
回答1:
you can either catch the SIGINT or write a signal handler. use the code below:
signal(SIGINT, sig_handler);
void sig_handler(int signo)
{
if (signo == SIGINT)
printf("received SIGINT\n");
}
来源:https://stackoverflow.com/questions/40474600/how-to-prevent-sigint-in-child-process-from-propagating-to-and-killing-parent-pr