【问题标题】:system() function while SIGCHLD is ignored忽略 SIGCHLD 时的 system() 函数
【发布时间】:2021-09-27 21:05:12
【问题描述】:

这是我的代码示例

signal(SIGCHLD, SIG_IGN);

ret = system("ls -al");

if(ret < 0)
{
    perror("system failed");
    printf("return value is %d\n", ret);
}

ls -al 命令可以毫无问题地执行。

但是system()的返回值总是-1。在这种情况下,我无法得到命令的真正返回值。

一些参考资料说忽略 SIGCHLD 会影响system() 中的waitpid(),这就是为什么system 总是返回-1。

但更让我困惑的是:SIGCHLD 不是默认忽略的吗?那么为什么显式忽略 SIGCHLD 会导致这种情况呢?

谁能给我解释一下?

感谢@cnicutar,我现在了解忽略 SIGCHLD 的影响。

但是现在我想知道是否有任何方法可以在忽略 SIGCHLD 的情况下获取子进程的返回值?还是由于 POSIX 规范和操作系统实现,这是不可能的?

【问题讨论】:

标签: c linux unix signals child-process


【解决方案1】:

但更让我困惑的是:SIGCHLD 不是默认忽略的吗?

不,默认情况下它不会被忽略。默认情况下,根本没有处理程序,也不采取任何行动。

那么为什么显式忽略 SIGCHLD 会导致这种情况呢?

忽略SIGCHLD 有一个有趣的副作用:孩子不会变成僵尸

POSIX.1-2001 指定如果 SIGCHLD 的处置设置为 为 SIGCHLD 设置了 SIG_IGN 或 SA_NOCLDWAIT 标志(参见 sigaction(2)),那么终止的孩子不会变成僵尸,并且 对wait()waitpid() 的调用将阻塞,直到所有孩子 已终止,然后失败,errno 设置为 ECHILD。

也就是说,您无需再等待孩子,因为他们会自动收集。但是system(3) 期待一个孩子!所以waitpid 返回一个错误,system(3) 的行为。

【讨论】:

  • 谢谢!那么在忽略 SIGCHLD 的情况下,是否有可能获得命令的返回值?
  • 如果您查看&lt;signal.h&gt; 的POSIX 规范,您会发现SIGCHLD 的默认行为记录为I(忽略)。但是,这是signal(SIGCHLD, SIG_DFL) 的设置,与signal(SIGCHLD, SIG_IGN) 的设置不同。令人困惑!
  • @fabregaszy 不,我认为一旦您忽略 SIGCHLD,就无法获得返回码。 JonathanLeffler:非常棒的信息,谢谢!
  • @cnicutar 我认为,如果您想要返回,您可以在两者之间动态地将信号处理程序更改为DFT,然后在系统之后再次将其更改为IGN。避免僵尸并获得系统回报。让我知道我的理解是否正确..
猜你喜欢
  • 2015-12-14
  • 2017-03-28
  • 1970-01-01
  • 2010-10-12
  • 2013-07-06
  • 2023-03-07
  • 2018-04-20
  • 1970-01-01
相关资源
最近更新 更多