From: nobu.nakada@... Date: 2003-02-04T15:01:13+09:00 Subject: [ruby-dev:19481] Re: pipe reopen なかだです。 At Mon, 27 Jan 2003 12:46:43 +0900, Nobuyoshi-Nakada wrote: > 一応こんなのを考えてみましたが、どうもlinux(というかglibc)では、 > fdopen()のときのモードを覚えておいてそれに合わない操作はエラー > になるようで、fptr->fからは書き込みはできないようです。 stdio objectを使い回しすべきなのは、descriptorが1..2のときでは なく、stdin,stdout,stderrのときではないかという気がして来ました。 この二つは通常は同じことですが、STDIN.closeしてしまうと別です。 Index: io.c =================================================================== RCS file: /cvs/ruby/src/ruby/io.c,v retrieving revision 1.182 diff -u -2 -p -r1.182 io.c --- io.c 16 Jan 2003 07:34:01 -0000 1.182 +++ io.c 28 Jan 2003 13:03:01 -0000 @@ -2291,4 +2291,5 @@ io_reopen(io, nfile) { OpenFile *fptr, *orig; + FILE *f; char *mode; int fd; @@ -2304,11 +2305,9 @@ io_reopen(io, nfile) if (fptr == orig) return io; if (orig->mode & FMODE_READABLE) { - pos = io_tell(orig); + io_fflush(GetWriteFile(orig), orig); + pos = ftello(orig->f); } - if (orig->f2) { - io_fflush(orig->f2, orig); - } - else if (orig->mode & FMODE_WRITABLE) { - io_fflush(orig->f, orig); + if (fptr->f2) { + io_fflush(fptr->f2, orig); } rb_thread_fd_close(fileno(fptr->f)); @@ -2324,6 +2323,7 @@ io_reopen(io, nfile) mode = rb_io_mode_string(fptr); - fd = fileno(fptr->f); - if (fd < 3) { + f = fptr->f; + fd = fileno(f); + if (f == stdin || f == stdout || f == stderr) { clearerr(fptr->f); /* need to keep stdio objects */ @@ -2342,14 +2342,7 @@ io_reopen(io, nfile) } - if (fptr->f2) { - fd = fileno(fptr->f2); - fclose(fptr->f2); - if (orig->f2) { - if (dup2(fileno(orig->f2), fd) < 0) - rb_sys_fail(orig->path); - fptr->f2 = rb_fdopen(fd, "w"); - } - else { - fptr->f2 = 0; + if (fptr->f2 && fd != fileno(fptr->f2)) { + if (dup2(fileno(GetWriteFile(orig)), fileno(fptr->f2)) < 0) { + rb_sys_fail(orig->path); } } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦