errno set in child process after fork - OSX
c, errno, fork, macos, unix
Solution
Curious...I can reproduce the problem on Mac OS X 10.9 Mavericks with GCC 4.8.2 and with Clang.
POSIX says that some functions that fail will set `errno` (and `fork()` is one of those functions), but does not say that functions that succeed will not set `errno`. For example, on Solaris, many standard I/O functions set `errno` if the output stream is not a terminal. However, resetting `errno = 0;` after the `printf()` doesn't alter the behaviour on Mac OS X.
POSIX 2008 (System Interfaces — General Information: 3. Error numbers):
Some functions provide the error number in a variable accessed through the symbol `errno`, defined by including the `<errno.h>` header. The value of `errno` should only be examined when it is indicated to be valid by a function's return value. No function in this volume of POSIX.1-2008 shall set `errno` to zero. For each thread of a process, the value of `errno` shall not be affected by function calls or assignments to `errno` by other threads.
If `fork()` failed, then `errno` would be set to indicate the failure. When it succeeds, it is not technically valid to inspect `errno`. And this is a demonstration of why.
Problem
here's a weird thing I found today on Mac OSX. After a fork, which has succeeded, errno is set at 0 in the father's process (as expected), but set at 22 in the child process. Here's the source-code : ``` #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); } ``` And the execution track : ``` 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. ``` As far as I know, and according to the Opengroup specifications, "The new process (child process) shall be an exact copy of the calling process (parent process) except as detailed below [...]", including the value of the global variable errno -_- Does anyone have a clue to explain that undesired behavior ?