IO#gets raise IOError when not writable

e$B$3$s$K$A$Oe(B sheepman e$B$G$9!#e(B

e$B0J2<$N$h$&$K%Q%$%W$re(B IO#close_write e$B$9$k$He(B IO#gets
e$B$G%(%i!<$K$J$j$^$9!#e(B

$ cat t.rb
io = IO.popen(“cat”, “r+”)
io.puts(“foo”)
io.close_write
p io.gets

$ ruby-1.8 -v t.rb
ruby 1.8.6 (2007-12-02 patchlevel 5000) [i686-linux]
“foo\n”

$ ruby-1.9 -v t.rb
ruby 1.9.0 (2008-01-30 revision 15239) [i686-linux]
t.rb:4:in gets': closed stream (IOError) from t.rb:4:in

e$B$J$+$@$G$9!#e(B

At Wed, 30 Jan 2008 23:47:30 +0900,
sheepman wrote in [ruby-dev:33532]:

e$B0J2<$N$h$&$K%Q%$%W$re(B IO#close_write e$B$9$k$He(B IO#gets e$B$G%(%i!<$K$J$j$^$9!#e(B

duplexe$B$5$l$?=q$-9~$_MQ$Ne(BIOe$B$,e(Bclosee$B$5$l$?$^$^;D$C$F$$$k$?$a$G$9$M!#e(B

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;
    }

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:33537] Re: IO#gets raise IOError when not
writable”
on Thu, 31 Jan 2008 00:45:11 +0900, Nobuyoshi N.
[email protected] writes:

|At Wed, 30 Jan 2008 23:47:30 +0900,
|sheepman wrote in [ruby-dev:33532]:
|> e$B0J2<$N$h$&$K%Q%$%W$re(B IO#close_write e$B$9$k$He(B IO#gets e$B$G%(%i!<$K$J$j$^$9!#e(B
|
|duplexe$B$5$l$?=q$-9~$_MQ$Ne(BIOe$B$,e(Bclosee$B$5$l$?$^$^;D$C$F$$$k$?$a$G$9$M!#e(B

e$B%3%_%C%H$7$F$/$@$5$$!#e(B