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

ruby-changes:15748

From: nobu <ko1@a...>
Date: Sat, 8 May 2010 23:07:53 +0900 (JST)
Subject: [ruby-changes:15748] Ruby:r27676 (trunk): * ext/io/console/console.c (ttymode): save dupped file descriptors

nobu	2010-05-08 23:07:32 +0900 (Sat, 08 May 2010)

  New Revision: 27676

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

  Log:
    * ext/io/console/console.c (ttymode): save dupped file descriptors
      and restore tty modes using them, so that original modes can be
      restored even if orignal fds are closed.  [ruby-dev:41225]

  Modified files:
    trunk/ChangeLog
    trunk/ext/io/console/console.c
    trunk/ext/io/console/extconf.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 27675)
+++ ChangeLog	(revision 27676)
@@ -1,3 +1,9 @@
+Sat May  8 23:07:28 2010  Nobuyoshi Nakada  <nobu@r...>
+
+	* ext/io/console/console.c (ttymode): save dupped file descriptors
+	  and restore tty modes using them, so that original modes can be
+	  restored even if orignal fds are closed.  [ruby-dev:41225]
+
 Sat May  8 13:48:31 2010  Marc-Andre Lafortune  <ruby-core@m...>
 
 	* array.c (rb_ary_fetch, rb_ary_splice, rb_ary_store): Improve
Index: ext/io/console/console.c
===================================================================
--- ext/io/console/console.c	(revision 27675)
+++ ext/io/console/console.c	(revision 27676)
@@ -173,6 +173,23 @@
 
 #define FD_PER_IO 2
 
+#if defined HAVE_DUP3
+#define dup_private(fd) dup3((fd), -1, O_CLOEXEC)
+#elif defined F_DUPFD_CLOEXEC
+#define dup_private(fd) fcntl((fd), F_DUPFD_CLOEXEC)
+#elif defined O_CLOEXEC
+static inline int
+dup_private(int fd)
+{
+    fd = dup(fd);
+    if (fd != -1) fcntl(fd, F_SETFD, O_CLOEXEC);
+    return fd;
+}
+#define dup_private(fd) dup_private(fd)
+#else
+#define dup_private(fd) dup(fd)
+#endif
+
 static VALUE
 ttymode(VALUE io, VALUE (*func)(VALUE), void (*setter)(conmode *))
 {
@@ -180,6 +197,7 @@
     int status = -1;
     int error = 0;
     int fd[FD_PER_IO];
+    int tmpfd, dupped = 0;
     conmode t[FD_PER_IO];
     VALUE result = Qnil;
 
@@ -187,6 +205,10 @@
     fd[0] = GetReadFD(fptr);
     if (fd[0] != -1) {
 	if (set_ttymode(fd[0], t+0, setter)) {
+	    if ((tmpfd = dup_private(fd[0])) != -1) {
+		fd[0] = tmpfd;
+		dupped |= 1 << 0;
+	    }
 	    status = 0;
 	}
 	else {
@@ -197,6 +219,10 @@
     fd[1] = GetWriteFD(fptr);
     if (fd[1] != -1 && fd[1] != fd[0]) {
 	if (set_ttymode(fd[1], t+1, setter)) {
+	    if ((tmpfd = dup_private(fd[1])) != -1) {
+		fd[1] = tmpfd;
+		dupped |= 1 << 1;
+	    }
 	    status = 0;
 	}
 	else {
@@ -207,18 +233,19 @@
     if (status == 0) {
 	result = rb_protect(func, io, &status);
     }
-    GetOpenFile(io, fptr);
-    if (fd[0] != -1 && fd[0] == GetReadFD(fptr)) {
+    if (fd[0] != -1) {
 	if (!setattr(fd[0], t+0)) {
 	    error = errno;
 	    status = -1;
 	}
+	if (dupped & (1 << 0)) close(fd[0]);
     }
-    if (fd[1] != -1 && fd[1] != fd[0] && fd[1] == GetWriteFD(fptr)) {
+    if (fd[1] != -1 && fd[1] != fd[0]) {
 	if (!setattr(fd[1], t+1)) {
 	    error = errno;
 	    status = -1;
 	}
+	if (dupped & (1 << 1)) close(fd[1]);
     }
     if (status) {
 	if (status == -1) {
Index: ext/io/console/extconf.rb
===================================================================
--- ext/io/console/extconf.rb	(revision 27675)
+++ ext/io/console/extconf.rb	(revision 27676)
@@ -14,6 +14,7 @@
 end
 have_header("sys/ioctl.h")
 have_func("rb_io_get_write_io", "ruby/io.h")
+have_func("dup3", "unistd.h")
 if ok
   create_makefile("io/console")
 end

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

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