首页 > 解决方案 > Linux system() 返回 -1,ERRNO = 10 无子进程

问题描述

当我在 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。

标签: crhel7

解决方案


system只有在初始创建子进程(通过fork)或收集其退出状态(通过wait)失败时,才能返回值 -1 。由于传递给 的命令有问题,这些事情都不会发生system,因为该命令是在子进程中解释的。该命令的问题将显示为system返回一个s不等于 0 或 -1 的值,并且其中一个WIFEXITED(s) && WEXITSTATUS(s) != 0WIFSIGNALED(s)为真。(宏WIFEXITEDWIFSIGNALEDWEXITSTATUS在 中定义sys/wait.h。)(请参阅POSIX 规范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处理程序之间的不良交互造成的。获取“无子进程”(ECHILDerrno与此假设一致,因为wait已记录为生成该错误代码,但事实fork并非如此。但这只是一个假设。为了更好地诊断您的问题,我们需要查看一个完整的测试程序,我们可以自己编译和运行该程序,并观察与您完全相同的故障情况。请阅读并遵循https://stackoverflow.com/help/mcve上的说明。


推荐阅读