From: Nobuyoshi Nakada Date: 2008-01-31T00:45:11+09:00 Subject: [ruby-dev:33537] Re: IO#gets raise IOError when not writable なかだです。 At Wed, 30 Jan 2008 23:47:30 +0900, sheepman wrote in [ruby-dev:33532]: > 以下のようにパイプを IO#close_write すると IO#gets でエラーになります。 duplexされた書き込み用のIOがcloseされたまま残っているためですね。 Index: io.c =================================================================== --- io.c (revision 15334) +++ io.c (working copy) @@ -2785,5 +2785,12 @@ rb_io_close_read(VALUE io) write_io = GetWriteIO(io); if (io != write_io) { + rb_io_t *wfptr; fptr_finalize(fptr, Qfalse); + GetOpenFile(write_io, wfptr); + if (fptr->refcnt < LONG_MAX) { + wfptr->refcnt++; + RFILE(io)->fptr = wfptr; + rb_io_fptr_finalize(fptr); + } return Qnil; } @@ -2818,10 +2825,11 @@ rb_io_close_write(VALUE io) { rb_io_t *fptr; + VALUE write_io; if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) { rb_raise(rb_eSecurityError, "Insecure: can't close"); } - io = GetWriteIO(io); - GetOpenFile(io, fptr); + write_io = GetWriteIO(io); + GetOpenFile(write_io, fptr); if (is_socket(fptr->fd, fptr->path)) { #ifndef SHUT_WR @@ -2832,5 +2840,5 @@ rb_io_close_write(VALUE io) fptr->mode &= ~FMODE_WRITABLE; if (!(fptr->mode & FMODE_READABLE)) - return rb_io_close(io); + return rb_io_close(write_io); return Qnil; } @@ -2839,5 +2847,12 @@ rb_io_close_write(VALUE io) rb_raise(rb_eIOError, "closing non-duplex IO for writing"); } - return rb_io_close(io); + + rb_io_close(write_io); + if (io != write_io) { + GetOpenFile(io, fptr); + fptr->tied_io_for_writing = 0; + fptr->mode &= ~FMODE_DUPLEX; + } + return Qnil; } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦