From 5ab9e9f617934fae8f85ceb6db398dbf1e93471d Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 4 Jul 2017 17:03:07 +0300 Subject: os/fileio: Add msgpack_file_write function --- src/nvim/os/fileio.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/nvim/os/fileio.c') diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c index 4309ac723c..d16746b7bf 100644 --- a/src/nvim/os/fileio.c +++ b/src/nvim/os/fileio.c @@ -26,6 +26,7 @@ #include "nvim/globals.h" #include "nvim/rbuffer.h" #include "nvim/macros.h" +#include "nvim/message.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/fileio.c.generated.h" @@ -345,3 +346,23 @@ ptrdiff_t file_skip(FileDescriptor *const fp, const size_t size) return (ptrdiff_t)read_bytes; } + +/// Msgpack callback for writing to a file +/// +/// @param data File to write to. +/// @param[in] buf Data to write. +/// @param[in] len Length of the data to write. +/// +/// @return 0 in case of success, -1 in case of error. +int msgpack_file_write(void *data, const char *buf, size_t len) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +{ + assert(len < PTRDIFF_MAX); + const ptrdiff_t written_bytes = file_write((FileDescriptor *)data, buf, len); + if (written_bytes < 0) { + emsgf(_("E5420: Failed to write to file: %s"), + os_strerror((int)written_bytes)); + return -1; + } + return 0; +} -- cgit From 72b3fd96642e7b2c268e17953de3b2ed995eb3b4 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 4 Jul 2017 17:08:43 +0300 Subject: os/fileio: Add ability to use os/fileio.c for file descriptors Code imported from #6299 --- src/nvim/os/fileio.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) (limited to 'src/nvim/os/fileio.c') diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c index d16746b7bf..0ed0ae87e3 100644 --- a/src/nvim/os/fileio.c +++ b/src/nvim/os/fileio.c @@ -49,7 +49,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; // -V:FLAG:501 #define FLAG(flags, flag, fcntl_flags, wrval, cond) \ @@ -74,14 +73,35 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname, FLAG(flags, kFileNoSymlink, O_NOFOLLOW, kNone, true); #endif #undef FLAG + // wr is used for kFileReadOnly flag, but on + // QB:neovim-qb-slave-ubuntu-12-04-64bit it still errors out with + // `error: variable ‘wr’ set but not used [-Werror=unused-but-set-variable]` + (void)wr; - 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)); +} - 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. +/// +/// @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) + 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); @@ -115,6 +135,26 @@ 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. +/// +/// @return [allocated] Opened file or NULL in case of error. +FileDescriptor *file_open_fd_new(int *const error, const int fd, const bool wr) + 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)) != 0) { + xfree(fp); + return NULL; + } + return fp; +} + /// Close file and free its buffer /// /// @param[in,out] fp File to close. -- cgit From 7109f63e3cf70ffc4581f3dfb6132632413e4817 Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 4 Jul 2017 19:48:26 +0300 Subject: main: Flush file in place of closing it, also do error reporting Apparently on travis OS X systems it crashes when cleaning up streams with stdout closed: (lldb) bt all * thread #1: tid = 0x0000, 0x00007fff8703df06 libsystem_kernel.dylib`__pthread_kill + 10, stop reason = signal SIGSTOP * frame #0: 0x00007fff8703df06 libsystem_kernel.dylib`__pthread_kill + 10 frame #1: 0x00007fff93a764ec libsystem_pthread.dylib`pthread_kill + 90 frame #2: 0x00007fff97c056df libsystem_c.dylib`abort + 129 frame #3: 0x00007fff97bccdd8 libsystem_c.dylib`__assert_rtn + 321 frame #4: 0x0000000107a4e106 nvim`uv__close(fd=) + 102 at core.c:521 frame #5: 0x0000000107a5307d nvim`uv__loop_close(loop=0x00007fff5847c018) + 77 at loop.c:118 frame #6: 0x0000000107a4d149 nvim`uv_loop_close(loop=0x00007fff5847c018) + 57 at uv-common.c:626 frame #7: 0x000000010783e5bc nvim`stream_set_blocking(fd=0, blocking=true) + 204 at stream.c:34 frame #8: 0x000000010795d66b nvim`mch_exit(r=0) + 91 at os_unix.c:147 frame #9: 0x00000001078d5663 nvim`command_line_scan(parmp=0x00007fff5847c760) + 1779 at main.c:787 frame #10: 0x00000001078d4393 nvim`main(argc=2, argv=0x00007fff5847c898) + 163 at main.c:249 frame #11: 0x00007fff8cdd65ad libdyld.dylib`start + 1 frame #12: 0x00007fff8cdd65ad libdyld.dylib`start + 1 --- src/nvim/os/fileio.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/nvim/os/fileio.c') diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c index 0ed0ae87e3..5d68473982 100644 --- a/src/nvim/os/fileio.c +++ b/src/nvim/os/fileio.c @@ -400,9 +400,18 @@ int msgpack_file_write(void *data, const char *buf, size_t len) assert(len < PTRDIFF_MAX); const ptrdiff_t written_bytes = file_write((FileDescriptor *)data, buf, len); if (written_bytes < 0) { - emsgf(_("E5420: Failed to write to file: %s"), - os_strerror((int)written_bytes)); - return -1; + return msgpack_file_write_error((int)written_bytes); } return 0; } + +/// Print error which occurs when failing to write msgpack data +/// +/// @param[in] error Error code of the error to print. +/// +/// @return -1 (error return for msgpack_packer callbacks). +int msgpack_file_write_error(const int error) +{ + emsgf(_("E5420: Failed to write to file: %s"), os_strerror(error)); + return -1; +} -- cgit