aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/os/fileio.c
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2017-03-19 16:55:37 +0300
committerZyX <kp-pav@yandex.ru>2017-03-19 16:56:00 +0300
commitbd798a3267a496c644b339c45189b09e2a952014 (patch)
treeaf4dd543f54bd166b5b288484551df26995179d7 /src/nvim/os/fileio.c
parentfdfa1ed578afd41a68f05c88dc419d88051b7240 (diff)
downloadrneovim-bd798a3267a496c644b339c45189b09e2a952014.tar.gz
rneovim-bd798a3267a496c644b339c45189b09e2a952014.tar.bz2
rneovim-bd798a3267a496c644b339c45189b09e2a952014.zip
getchar: Use fileio instead of fdopen
Problem: as fileio is cached and reads blocks this is going to wait until either EOF or reading enough characters to fill rbuffer. This is not good when reading user input from stdin as script.
Diffstat (limited to 'src/nvim/os/fileio.c')
-rw-r--r--src/nvim/os/fileio.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c
index 775f2bd449..3742fd53de 100644
--- a/src/nvim/os/fileio.c
+++ b/src/nvim/os/fileio.c
@@ -45,7 +45,6 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname,
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
int os_open_flags = 0;
- int fd;
TriState wr = kNone;
#define FLAG(flags, flag, fcntl_flags, wrval, cond) \
do { \
@@ -70,13 +69,33 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname,
#endif
#undef FLAG
- fd = os_open(fname, os_open_flags, mode);
+ const int fd = os_open(fname, os_open_flags, mode);
if (fd < 0) {
return fd;
}
+ return file_open_fd(ret_fp, fd, (wr == kTrue), mode);
+}
- ret_fp->wr = (wr == kTrue);
+/// Wrap file descriptor with FileDescriptor structure
+///
+/// @warning File descriptor wrapped like this must not be accessed by other
+/// means.
+///
+/// @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] 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)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ ret_fp->wr = wr;
ret_fp->fd = fd;
ret_fp->eof = false;
ret_fp->rv = rbuffer_new(kRWBufferSize);
@@ -110,6 +129,29 @@ FileDescriptor *file_open_new(int *const error, const char *const fname,
return fp;
}
+/// Like file_open_fd(), but allocate and return ret_fp
+///
+/// @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] 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)
+ 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) {
+ xfree(fp);
+ return NULL;
+ }
+ return fp;
+}
+
/// Close file and free its buffer
///
/// @param[in,out] fp File to close.