Linux system()返回-1,ERRNO = 10没有子进程[关闭]

问题描述 投票:1回答:1

当我在RHEL 7.4中运行以下C代码时:

errno = 0;

status = system("ls >> /tmp/test.txt");
sprintf(msg, "Value of errno: %d\n", errno);
sprintf(msg, "Status: %d ", status);
os_log_msg(msg);

我得到-1的返回码和errno = 10(没有子进程)。 /tmp/test.txt文件实际上已创建,因此它可以正常工作,但程序会看到非零返回码并退出。

问题是该命令在HP-UX 11.11中返回0,但我们迁移到RHEL 7.4,现在我们得到-1。

c rhel7
1个回答
5
投票

如果初始创建子进程(通过system)或其退出状态集合(通过fork)失败,则值-1只能由wait返回。由于传递给system的命令存在问题,因此这两件事都不会发生,因为该命令在子进程中被解释。该命令的问题将显示为system返回的值s不等于0或-1,并且WIFEXITED(s) && WEXITSTATUS(s) != 0WIFSIGNALED(s)为真。 (宏WIFEXITEDWIFSIGNALEDWEXITSTATUSsys/wait.h中定义。)(参见the POSIX specification for system以了解为什么会发生这种情况。)

fork故障通常仅发生在系统范围的资源耗尽和/或严重强加的资源配额中。例如,该程序打印

true: status=-1 errno=11 (Resource temporarily unavailable)

当我运行它。

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>

int main(void)
{
  struct rlimit rl;
  rl.rlim_cur = 1;
  rl.rlim_max = 1;
  setrlimit(RLIMIT_NPROC, &rl);

  int status = system("true");
  printf("true: status=%d errno=%d (%s)\n", status, errno, strerror(errno));
  return 0;
}

如果你有一个窃取等待状态的SIGCHLD处理程序,可能会发生wait内部的system故障。例如,该程序打印

true: status=-1 errno=10 (No child processes)

当我运行它。 (SIGCHLD处理程序可以通过其他几种方式干扰system;这只是我能想到的最短的演示程序。)

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>

int main(void)
{
  signal(SIGCHLD, SIG_IGN);

  int status = system("true");
  printf("true: status=%d errno=%d (%s)\n", status, errno, strerror(errno));
  return 0;
}

你说无论你传递给system的命令都能正确执行,但system仍然返回-1,这让我觉得你的问题是由于waitSIGCHLD处理程序之间的不良交互。在ECHILD中获得“无子过程”(errno)与此假设一致,因为wait被记录为产生该错误代码,而fork则不然。但这只是一个假设。为了更好地诊断你的问题,我们需要看到一个完整的测试程序,我们可以为自己编译和运行,并观察完全相同的故障情况。请阅读并按照https://stackoverflow.com/help/mcve上的说明进行操作。

© www.soinside.com 2019 - 2024. All rights reserved.