diff options
Diffstat (limited to 'src/nvim/os/fs.c')
-rw-r--r-- | src/nvim/os/fs.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 9ce50d4afd..383a2ac682 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -462,10 +462,11 @@ os_dup_dup: /// to false. Initial value is ignored. /// @param[out] ret_buf Buffer to write to. May be NULL if size is zero. /// @param[in] size Amount of bytes to read. +/// @param[in] non_blocking Do not restart syscall if EAGAIN was encountered. /// /// @return Number of bytes read or libuv error code (< 0). -ptrdiff_t os_read(const int fd, bool *ret_eof, char *const ret_buf, - const size_t size) +ptrdiff_t os_read(const int fd, bool *const ret_eof, char *const ret_buf, + const size_t size, const bool non_blocking) FUNC_ATTR_WARN_UNUSED_RESULT { *ret_eof = false; @@ -485,7 +486,9 @@ ptrdiff_t os_read(const int fd, bool *ret_eof, char *const ret_buf, if (cur_read_bytes < 0) { const int error = os_translate_sys_error(errno); errno = 0; - if (error == UV_EINTR || error == UV_EAGAIN) { + if (non_blocking && error == UV_EAGAIN) { + break; + } else if (error == UV_EINTR || error == UV_EAGAIN) { continue; } else if (error == UV_ENOMEM && !did_try_to_free) { try_to_free_memory(); @@ -515,7 +518,11 @@ ptrdiff_t os_read(const int fd, bool *ret_eof, char *const ret_buf, /// may change, it is incorrect to use data it points to after /// os_readv(). /// @param[in] iov_size Number of buffers in iov. -ptrdiff_t os_readv(int fd, bool *ret_eof, struct iovec *iov, size_t iov_size) +/// @param[in] non_blocking Do not restart syscall if EAGAIN was encountered. +/// +/// @return Number of bytes read or libuv error code (< 0). +ptrdiff_t os_readv(const int fd, bool *const ret_eof, struct iovec *iov, + size_t iov_size, const bool non_blocking) FUNC_ATTR_NONNULL_ALL { *ret_eof = false; @@ -548,7 +555,9 @@ ptrdiff_t os_readv(int fd, bool *ret_eof, struct iovec *iov, size_t iov_size) } else if (cur_read_bytes < 0) { const int error = os_translate_sys_error(errno); errno = 0; - if (error == UV_EINTR || error == UV_EAGAIN) { + if (non_blocking && error == UV_EAGAIN) { + break; + } else if (error == UV_EINTR || error == UV_EAGAIN) { continue; } else if (error == UV_ENOMEM && !did_try_to_free) { try_to_free_memory(); @@ -568,9 +577,11 @@ ptrdiff_t os_readv(int fd, bool *ret_eof, struct iovec *iov, size_t iov_size) /// @param[in] fd File descriptor to write to. /// @param[in] buf Data to write. May be NULL if size is zero. /// @param[in] size Amount of bytes to write. +/// @param[in] non_blocking Do not restart syscall if EAGAIN was encountered. /// /// @return Number of bytes written or libuv error code (< 0). -ptrdiff_t os_write(const int fd, const char *const buf, const size_t size) +ptrdiff_t os_write(const int fd, const char *const buf, const size_t size, + const bool non_blocking) FUNC_ATTR_WARN_UNUSED_RESULT { if (buf == NULL) { @@ -588,7 +599,9 @@ ptrdiff_t os_write(const int fd, const char *const buf, const size_t size) if (cur_written_bytes < 0) { const int error = os_translate_sys_error(errno); errno = 0; - if (error == UV_EINTR || error == UV_EAGAIN) { + if (non_blocking && error == UV_EAGAIN) { + break; + } else if (error == UV_EINTR || error == UV_EAGAIN) { continue; } else { return error; |