aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/os/fileio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/os/fileio.c')
-rw-r--r--src/nvim/os/fileio.c57
1 files changed, 40 insertions, 17 deletions
diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c
index 775f2bd449..4309ac723c 100644
--- a/src/nvim/os/fileio.c
+++ b/src/nvim/os/fileio.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// @file fileio.c
///
/// Buffered reading/writing to a file. Unlike fileio.c this is not dealing with
@@ -47,6 +50,7 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname,
int os_open_flags = 0;
int fd;
TriState wr = kNone;
+ // -V:FLAG:501
#define FLAG(flags, flag, fcntl_flags, wrval, cond) \
do { \
if (flags & flag) { \
@@ -100,7 +104,7 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname,
/// @return [allocated] Opened file or NULL in case of error.
FileDescriptor *file_open_new(int *const error, const char *const fname,
const int flags, const int mode)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
FileDescriptor *const fp = xmalloc(sizeof(*fp));
if ((*error = file_open(fp, fname, flags, mode)) != 0) {
@@ -113,27 +117,31 @@ FileDescriptor *file_open_new(int *const error, const char *const fname,
/// Close file and free its buffer
///
/// @param[in,out] fp File to close.
+/// @param[in] do_fsync If true, use fsync() to write changes to disk.
///
/// @return 0 or error code.
-int file_close(FileDescriptor *const fp) FUNC_ATTR_NONNULL_ALL
+int file_close(FileDescriptor *const fp, const bool do_fsync)
+ FUNC_ATTR_NONNULL_ALL
{
- const int error = file_fsync(fp);
- const int error2 = os_close(fp->fd);
+ const int flush_error = (do_fsync ? file_fsync(fp) : file_flush(fp));
+ const int close_error = os_close(fp->fd);
rbuffer_free(fp->rv);
- if (error2 != 0) {
- return error2;
+ if (close_error != 0) {
+ return close_error;
}
- return error;
+ return flush_error;
}
/// Close and free file obtained using file_open_new()
///
/// @param[in,out] fp File to close.
+/// @param[in] do_fsync If true, use fsync() to write changes to disk.
///
/// @return 0 or error code.
-int file_free(FileDescriptor *const fp) FUNC_ATTR_NONNULL_ALL
+int file_free(FileDescriptor *const fp, const bool do_fsync)
+ FUNC_ATTR_NONNULL_ALL
{
- const int ret = file_close(fp);
+ const int ret = file_close(fp, do_fsync);
xfree(fp);
return ret;
}
@@ -143,21 +151,36 @@ int file_free(FileDescriptor *const fp) FUNC_ATTR_NONNULL_ALL
/// @param[in,out] fp File to work with.
///
/// @return 0 or error code.
-int file_fsync(FileDescriptor *const fp)
+int file_flush(FileDescriptor *const fp)
FUNC_ATTR_NONNULL_ALL
{
if (!fp->wr) {
return 0;
}
file_rb_write_full_cb(fp->rv, fp);
- if (fp->_error != 0) {
- const int error = fp->_error;
- fp->_error = 0;
- return error;
+ const int error = fp->_error;
+ fp->_error = 0;
+ return error;
+}
+
+/// Flush file modifications to disk and run fsync()
+///
+/// @param[in,out] fp File to work with.
+///
+/// @return 0 or error code.
+int file_fsync(FileDescriptor *const fp)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (!fp->wr) {
+ return 0;
}
- const int error = os_fsync(fp->fd);
- if (error != UV_EINVAL && error != UV_EROFS) {
- return error;
+ const int flush_error = file_flush(fp);
+ if (flush_error != 0) {
+ return flush_error;
+ }
+ const int fsync_error = os_fsync(fp->fd);
+ if (fsync_error != UV_EINVAL && fsync_error != UV_EROFS) {
+ return fsync_error;
}
return 0;
}