Bug #13349
Updated by 0x6373 (Christian Schwabl) about 7 years ago
In io.c there are 2 Linux specific flags (O_CLOEXEC and O_NOINHERIT) which are set regardless of the operating system it is compiled on. Since AIX 7.1 /usr/include/fcntl.h defines O_CLOEXEC with the following statement: ``` ~~~ c #if _XOPEN_SOURCE >= 700 /* Currently as all 32 bits were used by _F flags, O_CLOEXEC and O_NOFOLLOW was defined as 64 bit. * Open function takes int as parameter hence we can't use 64bit O_CLOEXEC and O_NOFOLLOW for open. * instead of changing _FCLOEXEC and _FNOFOLLOW to 32 bit we have decided to use _FDEFERIND to define * O_CLOEXEC and _FCLREAD to define O_NOFOLLOW as there is no corresponding O_ flag for _FDEFERIND and _FCLREAD. */ #define O_CLOEXEC _FDEFERIND /* sets FD_CLOEXEC on open */ #define O_NOFOLLOW _FCLREAD /* do not follow symlinks */ /* In AIX TTY kernel extension, The terminal parameters are automatically * set to default values on first open. Hence O_TTY_INIT will be defined as zero. */ #define O_TTY_INIT 0 /* sets conforming tty state */ #endif /* _XOPEN_SOURCE >= 700 */ ``` ~~~ So, on AIX flag _FDEFERIND gets set, which causes all file open operations to /dev (i.e. /dev/null )to fail with EINVAL. The following patch encloses the linux-only part with "#ifdev __linux__" ``` diff ~~~ text --- io.c 2017-03-20 14:23:58.117976095 +0100 +++ io.c.new 2017-03-21 14:28:08.900827149 +0100 @@ -209,11 +209,13 @@ int rb_cloexec_open(const char *pathname, int flags, mode_t mode) { int ret; -#ifdef O_CLOEXEC +#ifdef __linux__ + #ifdef O_CLOEXEC /* O_CLOEXEC is available since Linux 2.6.23. Linux 2.6.18 silently ignore it. */ flags |= O_CLOEXEC; -#elif defined O_NOINHERIT + #elif defined O_NOINHERIT flags |= O_NOINHERIT; + #endif #endif ret = open(pathname, flags, mode); if (ret == -1) return -1; ``` ~~~ I tried this with ruby-2.0.0p468, ruby-2.2.6 and 2.3.x, but trunk is also affected since this part of the code hasn't changed in a while (end of 2011 from what i found). Is there any style-guide for this part of the code?