errno在fork之后设置在子进程中 - OSX

Rem*_*ant 3 c unix macos fork errno

这是我今天在Mac OSX上发现的一个奇怪的事情.

在成功的fork之后,在父进程中将errno设置为0(如预期的那样),但在子进程中设置为22.这是源代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h>
#include <errno.h>

int main(int nbArgs, char** args){
   int pid;
   errno = 0;
   printf("Errno value before the call to fork : %d.\n", errno);
   if ((pid = fork()) == -1){
      perror("Fork failed.");
      exit(1);
   }
   if (pid == 0){
      printf("Child : errno value : %d.\n", errno);
   }else{
      printf("Father : pid value : %d ; errno value : %d.\n", pid, errno);
      wait(NULL);
   }
   exit(0);
}
Run Code Online (Sandbox Code Playgroud)

和执行轨道:

Remis-Mac:TP3 venant$ ./errno_try
Errno value before the call to fork : 0.
Father : pid value : 9526 ; errno value : 0.
Child : errno value : 22.
Run Code Online (Sandbox Code Playgroud)

据我所知,根据Opengroup规范,"新流程(子流程)应该是调用流程(父流程)的精确副本,除非下面详细说明[...]",包括全局变量errno -_-

有没有人有解释这种不良行为的线索?

Jon*_*ler 5

好奇......我可以用GCC 4.8.2和Clang在Mac OS X 10.9 Mavericks上重现这个问题.

POSIX说一些失败的函数会设置errno(并且fork()是其中一个函数),但是并没有说成功的函数不会设置errno.例如,在Solaris上,errno如果输出流不是终端,则会设置许多标准I/O函数.但是,重置errno = 0;printf()不会改变Mac OS X上的行为.

POSIX 2008(系统接口 - 一般信息:3.错误号):

某些函数在通过符号访问的变量中提供错误编号errno,通过包含<errno.h>标头来定义.值errno时,则说明是由函数的返回值有效的只应进行检查.本卷POSIX.1-2008中的任何功能都不应设置errno为零.对于进程的每个线程,其值errno不应受函数调用或errno其他线程的赋值影响.

如果fork()失败,则将errno设置为指示失败.如果成功,检查技术上无效errno.这是为什么的示范.