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/