Actions
Bug #22391
closedFix propagation of `errno` in `rb_io_maybe_wait`.
Bug #22391:
Fix propagation of `errno` in `rb_io_maybe_wait`.
Description
When a write returns EAGAIN, we call rb_io_wait():
io_write()
io_fwrite()
io_binwrite()
io_binwrite_string()
io_binwrite_string_internal()
...
rb_io_maybe_wait_writable()
rb_io_maybe_wait()
return rb_io_wait(io, events, timeout)
if this wait also fails, it bubbles up to io_write() which reports it:
rb_syserr_new_path_in (after macro resolution) checks for a 0 error
code and aborts in that case:
if (n == 0) {
const char *s = !NIL_P(path) ? RSTRING_PTR(path) : "";
if (!func_name) func_name = "(null)";
rb_bug("rb_sys_fail_path_in(%s, %s) - errno == 0",
func_name, s);
}
Unfortunately, rb_io_wait() can invoke the fiber scheduler, running
arbitrary code that can clobber errno and trigger this rb_bug().
Fix this by preserving errno explicitly across the rb_io_wait() call.
Actions