diff --git a/io.c b/io.c index ab2ac296bd3e75..a8ba6ed98a627a 100644 --- a/io.c +++ b/io.c @@ -1355,11 +1355,13 @@ io_flush_buffer_sync(void *arg) fptr->wbuf.len = 0; return 0; } + if (0 <= r) { fptr->wbuf.off += (int)r; fptr->wbuf.len -= (int)r; errno = EAGAIN; } + return (VALUE)-1; } @@ -12303,7 +12305,11 @@ nogvl_wait_for(VALUE th, rb_io_t *fptr, short events, struct timeval *timeout) } int fd = fptr->fd; - if (fd == -1) return -1; + + if (fd == -1) { + errno = EBADF; + return -1; + } rb_fdset_t fds; int ret; diff --git a/thread.c b/thread.c index a5f1a00165d603..e1b194861add02 100644 --- a/thread.c +++ b/thread.c @@ -1675,6 +1675,10 @@ rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd) .th = rb_ec_thread_ptr(ec) }; + // `errno` is only valid when there is an actual error - but we can't + // extract that from the return value of `func` alone, so we clear any + // prior `errno` value here so that we can later check if it was set by + // `func` or not (as opposed to some previously set value). errno = 0; RB_VM_LOCK_ENTER();