Mercurial > vim
changeset 12857:ffdf2e4b5d9a v8.0.1305
patch 8.0.1305: writefile() never calls fsync()
commit https://github.com/vim/vim/commit/7567d0b115e332f61a9f390aaccdf7825b891227
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Nov 16 23:04:15 2017 +0100
patch 8.0.1305: writefile() never calls fsync()
Problem: Writefile() never calls fsync().
Solution: Follow the 'fsync' option with override to enable or disable.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 16 Nov 2017 23:15:05 +0100 |
parents | 4c4a02a946f0 |
children | 4f1870188845 |
files | runtime/doc/eval.txt src/evalfunc.c src/fileio.c src/globals.h src/testdir/test_writefile.vim src/version.c |
diffstat | 6 files changed, 39 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 8.0. Last change: 2017 Oct 28 +*eval.txt* For Vim version 8.0. Last change: 2017 Nov 16 VIM REFERENCE MANUAL by Bram Moolenaar @@ -8721,7 +8721,7 @@ winwidth({nr}) *winwidth()* Examples: > :echo "The current window has " . winwidth(0) . " columns." :if winwidth(0) <= 50 - : exe "normal 50\<C-W>|" + : 50 wincmd | :endif < For getting the terminal or screen size, see the 'columns' option. @@ -8762,8 +8762,17 @@ writefile({list}, {fname} [, {flags}]) appended to the file: > :call writefile(["foo"], "event.log", "a") :call writefile(["bar"], "event.log", "a") - -< All NL characters are replaced with a NUL character. +< + When {flags} contains "s" then fsync() is called after writing + the file. This flushes the file to disk, if possible. This + takes more time but avoids losing the file if the system + crashes. + When {flags} does not contain "S" or "s" then fsync is called + if the 'fsync' option is set. + When {flags} contains "S" then fsync() is not called, even + when 'fsync' is set. + + All NL characters are replaced with a NUL character. Inserting CR characters needs to be done before passing {list} to writefile(). An existing file is overwritten, if possible.
--- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -13348,6 +13348,9 @@ f_writefile(typval_T *argvars, typval_T { int binary = FALSE; int append = FALSE; +#ifdef HAVE_FSYNC + int do_fsync = p_fs; +#endif char_u *fname; FILE *fd; int ret = 0; @@ -13380,6 +13383,12 @@ f_writefile(typval_T *argvars, typval_T binary = TRUE; if (vim_strchr(arg2, 'a') != NULL) append = TRUE; +#ifdef HAVE_FSYNC + if (vim_strchr(arg2, 's') != NULL) + do_fsync = TRUE; + else if (vim_strchr(arg2, 'S') != NULL) + do_fsync = FALSE; +#endif } fname = get_tv_string_chk(&argvars[1]); @@ -13398,6 +13407,10 @@ f_writefile(typval_T *argvars, typval_T { if (write_list(fd, list, binary) == FAIL) ret = -1; +#ifdef HAVE_FSYNC + else if (do_fsync && fsync(fileno(fd)) != 0) + EMSG(_(e_fsync)); +#endif fclose(fd); }
--- a/src/fileio.c +++ b/src/fileio.c @@ -4771,7 +4771,7 @@ restore_backup: */ if (p_fs && fsync(fd) != 0 && !device) { - errmsg = (char_u *)_("E667: Fsync failed"); + errmsg = (char_u *)_(e_fsync); end = 0; } #endif
--- a/src/globals.h +++ b/src/globals.h @@ -1449,6 +1449,9 @@ EXTERN char_u e_isadir2[] INIT(= N_("E17 #ifdef FEAT_LIBCALL EXTERN char_u e_libcall[] INIT(= N_("E364: Library call failed for \"%s()\"")); #endif +#ifdef HAVE_FSYNC +EXTERN char_u e_fsync[] INIT(= N_("E667: Fsync failed")); +#endif #if defined(DYNAMIC_PERL) \ || defined(DYNAMIC_PYTHON) || defined(DYNAMIC_PYTHON3) \ || defined(DYNAMIC_RUBY) \
--- a/src/testdir/test_writefile.vim +++ b/src/testdir/test_writefile.vim @@ -93,3 +93,10 @@ func Test_nowrite_quit_split() endif bwipe Xfile endfunc + +func Test_writefile_sync_arg() + " This doesn't check if fsync() works, only that the argument is accepted. + call writefile(['one'], 'Xtest', 's') + call writefile(['two'], 'Xtest', 'S') + call delete('Xtest') +endfunc