How to prevent SIGINT in child process from propagating to and killing parent process?

余生颓废 提交于 2019-12-23 18:08:40

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!