[Bug #19624] Clean up backquote IO

It should not be hidden, since it can be grabbed by a fiber scheduler.
This commit is contained in:
Nobuyoshi Nakada 2023-09-20 21:32:40 +09:00
parent 7ffee5681f
commit ab637cad2b
2 changed files with 26 additions and 9 deletions

20
io.c
View File

@ -5574,12 +5574,9 @@ clear_codeconv(rb_io_t *fptr)
clear_writeconv(fptr);
}
void
rb_io_fptr_finalize_internal(void *ptr)
static void
rb_io_fptr_cleanup_all(rb_io_t *fptr)
{
rb_io_t *fptr = ptr;
if (!ptr) return;
fptr->pathv = Qnil;
if (0 <= fptr->fd)
rb_io_fptr_cleanup(fptr, TRUE);
@ -5587,7 +5584,14 @@ rb_io_fptr_finalize_internal(void *ptr)
free_io_buffer(&fptr->rbuf);
free_io_buffer(&fptr->wbuf);
clear_codeconv(fptr);
free(fptr);
}
void
rb_io_fptr_finalize_internal(void *ptr)
{
if (!ptr) return;
rb_io_fptr_cleanup_all(ptr);
free(ptr);
}
#undef rb_io_fptr_finalize
@ -10467,11 +10471,9 @@ rb_f_backquote(VALUE obj, VALUE str)
if (NIL_P(port)) return rb_str_new(0,0);
GetOpenFile(port, fptr);
rb_obj_hide(port);
result = read_all(fptr, remain_size(fptr), Qnil);
rb_io_close(port);
RFILE(port)->fptr = NULL;
rb_io_fptr_finalize(fptr);
rb_io_fptr_cleanup_all(fptr);
RB_GC_GUARD(port);
return result;

View File

@ -219,4 +219,19 @@ class TestFiberIO < Test::Unit::TestCase
assert_equal [[r], [w], []], result
end
end
def test_backquote
result = nil
thread = Thread.new do
scheduler = Scheduler.new
Fiber.set_scheduler scheduler
Fiber.schedule do
result = `#{EnvUtil.rubybin} -e "sleep 0.1;puts %[ok]"`
end
end
thread.join
assert_equal "ok\n", result
end
end