[英]How to prevent SIGINT in child process from propagating to and killing parent process?
我最近学会了如何做整个fork/exec/wait
事情,最后写了一些看起来像这样剥离的代码:
#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");
}
}
这很好,实际上最终打开sqlite3
shell,但有一个问题。 如果您从sqlite3
shell中Ctrl + C
,那么它也会终止父进程并且行printf("Hi\\n")
永远不会运行。
我假设这是因为SIGINT正在传播到父进程,并且在进一步研究之后,我读到SIGINT将终止同一组中的所有进程,这意味着因为父和子共享同一组,所以他们都是终止。
我尝试通过尝试调用setpgid
来解决这个问题:
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");
}
}
哪个运行正常,但这打破了sqlite3
提示。 此外,在这种情况下, Ctrl + C
仍然会杀死父级。 我决定尝试将它缩小甚至更多,然后发现一些奇怪的东西,并且难倒了。 只是将一个getpid()
调用放入fork将使execlp()
失败。
#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");
}
}
甚至不仅仅是对于sqlite3
,而是对于像execlp("ls", "ls")
这样的简单东西execlp("ls", "ls")
尽管这可能与原始问题无关)。
我有点过头了,我想知道是否有人能指出我正确的方向。 我不太清楚从这里做什么。
clang --version
:Apple LLVM 8.0.0版(clang-800.0.42.1) 你可以捕获SIGINT或写一个信号处理程序。 使用以下代码:
signal(SIGINT, sig_handler);
void sig_handler(int signo)
{
if (signo == SIGINT)
printf("received SIGINT\n");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.