How to prevent SIGINT in a child process from spreading and destroying the parent process?

I recently learned how to make the whole fork/exec/wait tag, and ended up writing code that looked like this:

 #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 pretty well, and the sqlite3 shell sqlite3 , but there is one problem. If you sqlite3 Ctrl + C from the sqlite3 shell, then it will also terminate the parent process, and the printf("Hi\n") will never start.

I assumed that this was due to the fact that SIGINT extended to the parent process, and, having studied it further, I read that SIGINT will terminate all processes in the same group, that is, since the parent and child have the same same group, they are both completed.

I tried to fix this by trying to call setpgid as follows:

 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 works fine, but that broke the sqlite3 . Moreover, Ctrl + C still killed the parent in this case. I decided to try to narrow it down even more, and then I found something strange and stalled. Simply placing the getpid() call in the fork will cause execlp() to crash.

 #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 for sqlite3 , but for simple things like execlp("ls", "ls") (this may not be related to the original question).

I'm a little over my head and I was wondering if anyone could point me in the right direction. I'm not quite sure what to do next.

  • I'm on OSX 10.11 and compiling with clang.
  • clang --version : Apple LLVM version 8.0.0 (clang-800.0.42.1)
+2
source share
1 answer

You can either catch SIGINT or write a signal handler. use the following code:

 signal(SIGINT, sig_handler); void sig_handler(int signo) { if (signo == SIGINT) printf("received SIGINT\n"); } 
-one
source

Source: https://habr.com/ru/post/1012135/


All Articles