[前][次][番号順一覧][スレッド一覧]

ruby-changes:32561

From: akr <ko1@a...>
Date: Sat, 18 Jan 2014 22:28:39 +0900 (JST)
Subject: [ruby-changes:32561] akr:r44640 (trunk): * io.c: Test O_CLOEXEC only once.

akr	2014-01-18 22:28:35 +0900 (Sat, 18 Jan 2014)

  New Revision: 44640

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=44640

  Log:
    * io.c: Test O_CLOEXEC only once.
      Patch by Eric Wong.  [ruby-core:59419] [Feature #9328]

  Modified files:
    trunk/ChangeLog
    trunk/io.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 44639)
+++ ChangeLog	(revision 44640)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Jan 18 22:25:53 2014  Tanaka Akira  <akr@f...>
+
+	* io.c: Test O_CLOEXEC only once.
+	  Patch by Eric Wong.  [ruby-core:59419] [Feature #9328]
+
 Sat Jan 18 21:24:49 2014  Tanaka Akira  <akr@f...>
 
 	* ext/socket/option.c: IP_MULTICAST_LOOP and IP_MULTICAST_TTL socket
Index: io.c
===================================================================
--- io.c	(revision 44639)
+++ io.c	(revision 44640)
@@ -228,10 +228,29 @@ rb_fd_fix_cloexec(int fd) https://github.com/ruby/ruby/blob/trunk/io.c#L228
     rb_update_max_fd(fd);
 }
 
+/* this is only called once */
+static int
+rb_fix_detect_o_cloexec(int fd)
+{
+#ifdef O_CLOEXEC
+    int flags = fcntl(fd, F_GETFD);
+
+    if (flags == -1)
+        rb_bug("rb_fix_detect_o_cloexec: fcntl(%d, F_GETFD) failed: %s", fd, strerror(errno));
+
+    if (flags & FD_CLOEXEC)
+	return 1;
+#endif /* fall through if O_CLOEXEC does not work: */
+    rb_maygvl_fd_fix_cloexec(fd);
+    return 0;
+}
+
 int
 rb_cloexec_open(const char *pathname, int flags, mode_t mode)
 {
     int ret;
+    static int o_cloexec_state = -1; /* <0: unknown, 0: ignored, >0: working */
+
 #ifdef O_CLOEXEC
     /* O_CLOEXEC is available since Linux 2.6.23.  Linux 2.6.18 silently ignore it. */
     flags |= O_CLOEXEC;
@@ -240,7 +259,13 @@ rb_cloexec_open(const char *pathname, in https://github.com/ruby/ruby/blob/trunk/io.c#L259
 #endif
     ret = open(pathname, flags, mode);
     if (ret == -1) return -1;
-    rb_maygvl_fd_fix_cloexec(ret);
+    if (ret <= 2 || o_cloexec_state == 0) {
+	rb_maygvl_fd_fix_cloexec(ret);
+    } else if (o_cloexec_state > 0) {
+	return ret;
+    } else {
+	o_cloexec_state = rb_fix_detect_o_cloexec(ret);
+    }
     return ret;
 }
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]