diff options
Diffstat (limited to 'src/nvim/os/fileio.c')
-rw-r--r-- | src/nvim/os/fileio.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c index 3742fd53de..70ed49c3aa 100644 --- a/src/nvim/os/fileio.c +++ b/src/nvim/os/fileio.c @@ -74,7 +74,7 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname, if (fd < 0) { return fd; } - return file_open_fd(ret_fp, fd, (wr == kTrue), mode); + return file_open_fd(ret_fp, fd, flags, mode); } /// Wrap file descriptor with FileDescriptor structure @@ -85,17 +85,24 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname, /// @param[out] ret_fp Address where information needed for reading from or /// writing to a file is saved /// @param[in] fd File descriptor to wrap. -/// @param[in] wr True if fd is opened for writing only, false if it is read -/// only. +/// @param[in] flags Flags, @see FileOpenFlags. Currently reading from and +/// writing to the file at once is not supported, so either +/// FILE_WRITE_ONLY or FILE_READ_ONLY is required. /// @param[in] mode Permissions for the newly created file (ignored if flags /// does not have FILE_CREATE\*). /// /// @return Error code (@see os_strerror()) or 0. Currently always returns 0. int file_open_fd(FileDescriptor *const ret_fp, const int fd, - const bool wr, const int mode) + const int flags, const int mode) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { - ret_fp->wr = wr; + ret_fp->wr = !!(flags & (kFileCreate|kFileCreateOnly + |kFileTruncate + |kFileAppend + |kFileWriteOnly)); + ret_fp->non_blocking = !!(flags & kFileNonBlocking); + // Non-blocking writes not supported currently. + assert(!ret_fp->wr || !ret_fp->non_blocking); ret_fp->fd = fd; ret_fp->eof = false; ret_fp->rv = rbuffer_new(kRWBufferSize); @@ -134,18 +141,17 @@ FileDescriptor *file_open_new(int *const error, const char *const fname, /// @param[out] error Error code, @see os_strerror(). Is set to zero on /// success. /// @param[in] fd File descriptor to wrap. -/// @param[in] wr True if fd is opened for writing only, false if it is read -/// only. +/// @param[in] flags Flags, @see FileOpenFlags. /// @param[in] mode Permissions for the newly created file (ignored if flags /// does not have FILE_CREATE\*). /// /// @return [allocated] Opened file or NULL in case of error. FileDescriptor *file_open_fd_new(int *const error, const int fd, - const bool wr, const int mode) + const int flags, const int mode) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT { FileDescriptor *const fp = xmalloc(sizeof(*fp)); - if ((*error = file_open_fd(fp, fd, wr, mode)) != 0) { + if ((*error = file_open_fd(fp, fd, flags, mode)) != 0) { xfree(fp); return NULL; } @@ -224,7 +230,8 @@ static void file_rb_write_full_cb(RBuffer *const rv, FileDescriptor *const fp) return; } const size_t read_bytes = rbuffer_read(rv, writebuf, kRWBufferSize); - const ptrdiff_t wres = os_write(fp->fd, writebuf, read_bytes); + const ptrdiff_t wres = os_write(fp->fd, writebuf, read_bytes, + fp->non_blocking); if (wres != (ptrdiff_t)read_bytes) { if (wres >= 0) { fp->_error = UV_EIO; @@ -274,7 +281,7 @@ ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf, }; assert(write_count == kRWBufferSize); const ptrdiff_t r_ret = os_readv(fp->fd, &fp->eof, iov, - ARRAY_SIZE(iov)); + ARRAY_SIZE(iov), fp->non_blocking); if (r_ret > 0) { if (r_ret > (ptrdiff_t)read_remaining) { rbuffer_produced(rv, (size_t)(r_ret - (ptrdiff_t)read_remaining)); @@ -290,7 +297,8 @@ ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf, if (read_remaining >= kRWBufferSize) { // …otherwise leave RBuffer empty and populate only target buffer, // because filtering information through rbuffer will be more syscalls. - const ptrdiff_t r_ret = os_read(fp->fd, &fp->eof, buf, read_remaining); + const ptrdiff_t r_ret = os_read(fp->fd, &fp->eof, buf, read_remaining, + fp->non_blocking); if (r_ret >= 0) { read_remaining -= (size_t)r_ret; return (ptrdiff_t)(size - read_remaining); @@ -301,7 +309,7 @@ ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf, size_t write_count; const ptrdiff_t r_ret = os_read(fp->fd, &fp->eof, rbuffer_write_ptr(rv, &write_count), - kRWBufferSize); + kRWBufferSize, fp->non_blocking); assert(write_count == kRWBufferSize); if (r_ret > 0) { rbuffer_produced(rv, (size_t)r_ret); @@ -311,6 +319,10 @@ ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf, } #endif } + if (fp->non_blocking) { + // Allow only at most one os_read[v] call. + break; + } } return (ptrdiff_t)(size - read_remaining); } |