【发布时间】:2013-07-06 03:20:31
【问题描述】:
system()states 的手册页“在命令执行期间,SIGCHLD 将被阻塞”
在我的代码中,我正在为SIGCHLD 安装一个处理程序,它将一些内容写入日志并忽略信号。我这样做是为了了解在我的日志中退出的子进程并避免僵尸进程。
当我使用system() 调用时出现问题。有了这个处理程序system() 总是返回-1 而不是孩子的退出代码。但根据手册页的上述引用,system() 应该处理来自孩子的信号。
我做错了什么?
我的代码如下:
static void handleSignal(int signum, siginfo_t* inf, void* ctx) {
cout << "in signal " << signum << endl;
}
int main() {
struct sigaction chldsa, prevchld;
chldsa.sa_sigaction = &handleSignal;
sigemptyset(&chldsa.sa_mask);
chldsa.sa_flags = SA_SIGINFO | SA_RESTART | SA_NOCLDSTOP | SA_NOCLDWAIT;
if (sigaction(SIGCHLD, &chldsa, &prevchld) == -1) {
cout << "Failed setting sigaction SIGCHLD " << errno;
}
int x = system("exit 1");
cout << "RET=" << x << endl;
}
【问题讨论】:
-
首先,那是 C++,而不是 C。它们是不同的语言,即使它们有相似之处。其次,Linux 中的
system(string)相当于在子进程中执行execl("/bin/sh", "sh", "-c", string, NULL);(根据POSIX.1 兼容性的要求)。为什么不自己写呢?只要不忽略 SIGCHLD (SIG_IGN),它是一个非常简单的函数来实现。需要一个例子吗?虽然它确实解决了您的问题,但它并不完全是您问题的答案——除非您认为 “不要使用 system(),而是使用您自己的版本” 是一个有效的答案。 -
不使用
system()不是一种选择。这不是我的代码做的。 -
另外,
execl()AFAIK 不等同于system(),因为它不做fork() -
当我使用
system()时你确实写了“。另外,“execl()in a child process”的哪一部分你没看懂? -
阅读时错过的部分 :)