【问题标题】:Why does fork() return errno = 22 [duplicate]为什么 fork() 返回 errno = 22 [重复]
【发布时间】:2016-07-19 22:08:11
【问题描述】:

我有一个简单的程序,如下所示:-

int main(int argc, const char * argv[]) 
{
  printf ("Before Fork [%d][%d:%s]\n",getpid(),errno,strerror(errno));
  pid_t pid = fork();

  if (!pid) //CHILD PROCESS
  {
    printf ("In Child Process [%d  [%d:%s]\n",getpid(),errno,strerror(errno));
  }
  else 
  {
   while(1);
  }
}

这会产生输出:-

Before Fork [50083][0:Undefined error: 0]
In Child Process [50084][22:Invalid argument]

有谁知道为什么操作系统在 FORK 之后立即抛出 INVALID ARGUMENT 错误?

【问题讨论】:

  • You're not alone in your observation。选择的答案也适用于您。如果fork()成功,则errno中没有具体的值需要设置;只有当它失败时,你才能相信它有一个理由。
  • 明天可能是 33 岁
  • 如有疑问,请务必阅读相关手册页。在这种情况下,errno man page:“它的值只有在调用的返回值指示错误时才有意义
  • 你运行的是什么操作系统?
  • @everyone :- 正如 WhozCraig 和 michi 提到的,由于 fork 有效(不返回 -1),我们不能(而不应该)处理 errno 值。

标签: c linux process fork


【解决方案1】:

这只是一个猜测,但可能是因为 fork 变成了系统调用 clone()(查看 strace):

6952  write(1, "Before Fork [6952][0:Success]\n", 30) = 30
6952  clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f55f10e19d0) = 6953
6953  write(1, "In Child Process [6953  [0:Succe"..., 36) = 36

clone(2) 手册页说:

EINVAL 在指定零值时由 clone() 返回 对于 child_stack。

我没有遍历内核代码,但可能是因为child_stack=0 而设置了 errno,但在完成子创建时不会因为标志而出错。

再一次.... strace 可能会被搞砸,因为 SIGCHLD 不可能属于克隆标志。

【讨论】:

  • 没有。除非前面的函数调用失败(在这种情况下没有失败),否则使用 errno 是未定义的行为。
  • 我没有说它是在规范中定义的。我正在调查原因。 errno 发生了一些变化,唯一的嫌疑人似乎是写入和克隆。我不认为这是写的。
猜你喜欢
  • 2020-03-30
  • 2015-06-05
  • 2021-05-04
  • 1970-01-01
  • 2017-02-14
  • 2012-06-11
  • 2019-06-29
  • 2011-07-31
  • 1970-01-01
相关资源
最近更新 更多