Project

General

Profile

Actions

Bug #13349

closed

Ruby unable to open files in /dev on AIX if compiled on AIX 7.1 or later

Added by 0x6373 (Christian Schwabl) about 7 years ago. Updated over 4 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:80267]

Description

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:

#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__"

--- a/io.c        2017-03-20 14:23:58.117976095 +0100
+++ b/io.c        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;

This patch applies against ruby-2.0.0p468 since i had a working reference of this compiled on AIX 5.3.

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?

Actions #1

Updated by 0x6373 (Christian Schwabl) about 7 years ago

  • Description updated (diff)
Actions #2

Updated by 0x6373 (Christian Schwabl) about 7 years ago

  • Description updated (diff)

Updated by 0x6373 (Christian Schwabl) about 7 years ago

  • Description updated (diff)

fixed syntax

Updated by 0x6373 (Christian Schwabl) about 7 years ago

  • Description updated (diff)

Clarified that the supplied patch applies to ruby-2.0.0p468

Updated by nobu (Nobuyoshi Nakada) about 7 years ago

  • Description updated (diff)
  • Status changed from Open to Feedback

It is rather AIX-specific issue.
O_CLOEXEC is defined on BSDs and mac OS, and O_NOINHERIT is defined on Windows.
So your patch is not acceptable as-is.

And do operations on regular files (not device files) succeed?
If so, it should be another reason not to accept.

Updated by kosaki (Motohiro KOSAKI) about 7 years ago

That's AIX's bug. Please contact the vendor and fix your OS.

Updated by 0x6373 (Christian Schwabl) about 7 years ago

Thanks for the comments, i just found a bug description from the vendor which seems to apply.
I will apply the fix for http://www-01.ibm.com/support/docview.wss?uid=isg1IV90904 today or tomorrow and will update this ticket.

Actions #8

Updated by jeremyevans0 (Jeremy Evans) over 4 years ago

  • Status changed from Feedback to Closed
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0