mirror of
https://github.com/ruby/ruby.git
synced 2025-09-17 01:23:57 +02:00
merge revision(s) 43112,43114,43117,43118: [Backport #8980]
* io.c (rb_io_close_read): keep fptr in write_io to be discarded, to fix freed pointer access when it is in use by other threads, and get rid of potential memory/fd leak. * io.c (rb_io_close_write): detach tied IO for writing before closing to get rid of race condition. [ruby-list:49598] * io.c (rb_io_close_read): duplex IO should wait its child process even after close_read. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@43144 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
3cfa0074d9
commit
514878d15c
4 changed files with 45 additions and 5 deletions
13
io.c
13
io.c
|
@ -4369,11 +4369,16 @@ rb_io_close_read(VALUE io)
|
|||
write_io = GetWriteIO(io);
|
||||
if (io != write_io) {
|
||||
rb_io_t *wfptr;
|
||||
rb_io_fptr_cleanup(fptr, FALSE);
|
||||
GetOpenFile(write_io, wfptr);
|
||||
wfptr->pid = fptr->pid;
|
||||
fptr->pid = 0;
|
||||
RFILE(io)->fptr = wfptr;
|
||||
RFILE(write_io)->fptr = NULL;
|
||||
rb_io_fptr_finalize(fptr);
|
||||
/* bind to write_io temporarily to get rid of memory/fd leak */
|
||||
fptr->tied_io_for_writing = 0;
|
||||
fptr->mode &= ~FMODE_DUPLEX;
|
||||
RFILE(write_io)->fptr = fptr;
|
||||
rb_io_fptr_cleanup(fptr, FALSE);
|
||||
/* should not finalize fptr because another thread may be reading it */
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
|
@ -4429,12 +4434,12 @@ rb_io_close_write(VALUE io)
|
|||
rb_raise(rb_eIOError, "closing non-duplex IO for writing");
|
||||
}
|
||||
|
||||
rb_io_close(write_io);
|
||||
if (io != write_io) {
|
||||
GetOpenFile(io, fptr);
|
||||
fptr->tied_io_for_writing = 0;
|
||||
fptr->mode &= ~FMODE_DUPLEX;
|
||||
}
|
||||
rb_io_close(write_io);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue