]> git.feebdaed.xyz Git - 0xmirror/vim.git/commitdiff
patch 9.1.2024: 'fsync' option cannot be set per buffer
authorglepnir <glephunter@gmail.com>
Sat, 27 Dec 2025 14:26:38 +0000 (14:26 +0000)
committerChristian Brabandt <cb@256bit.org>
Sat, 27 Dec 2025 14:32:47 +0000 (14:32 +0000)
Problem:  'fsync' option cannot be set per buffer
Solution: Make 'fsync' option global-local
          (glepnir)

closes: #19019

Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/doc/options.txt
runtime/doc/version9.txt
src/buffer.c
src/bufwrite.c
src/option.c
src/option.h
src/optiondefs.h
src/structs.h
src/testdir/test_options.vim
src/undo.c
src/version.c

index b1550dfcca2c946b4e245b24f5890b8da6505bef..67c8b29041f614d5772609f5695fa3bce96f2920 100644 (file)
@@ -1,4 +1,4 @@
-*options.txt*  For Vim version 9.1.  Last change: 2025 Dec 23
+*options.txt*  For Vim version 9.1.  Last change: 2025 Dec 27
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -4274,7 +4274,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 
                                        *'fsync'* *'fs'* *'nofsync'* *'nofs'*
 'fsync' 'fs'           boolean (default on)
-                       global
+                       global or local to buffer |global-local|
        When on, the library function fsync() will be called after writing a
        file.  This will flush a file to disk, ensuring that it is safely
        written even on filesystems which do metadata-only journaling.  This
@@ -4283,6 +4283,8 @@ A jump table for the options with a short description can be found at |Q_op|.
        turning this off increases the chances of data loss after a crash.  On
        systems without an fsync() implementation, this variable is always
        off.
+       This is a |global-local| option, so it can be set per buffer, for
+       example when writing to a slow filesystem.
        Also see 'swapsync' for controlling fsync() on swap files.
        'fsync' also applies to |writefile()| (unless a flag is used to
        overrule it) and when writing undo files (see |undo-persistence|).
index f1cfd09797d36b8cd813aeb02bfc877d77113e57..b626f2deadc5b182334f3acb71f8e055a353fdee 100644 (file)
@@ -1,4 +1,4 @@
-*version9.txt* For Vim version 9.1.  Last change: 2025 Dec 21
+*version9.txt* For Vim version 9.1.  Last change: 2025 Dec 27
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -41727,6 +41727,7 @@ Options: ~
 - 'guioptions': New value |'go-s'| to support fullscreen on MS-Windows GUI
   (see also the below platform specific change).
 - 'completepopup': Add more values to style popup windows.
+- 'fsync' is now a |global-local| option.
 
 Ex commands: ~
 - allow to specify a priority when defining a new sign |:sign-define|
index 52aa13de210dfb32240f2574e7d0b6fac0e8d8a2..7dca75307b9eb252f2e0c0b10cd81c9a70e25fb5 100644 (file)
@@ -2538,6 +2538,9 @@ free_buf_options(
     clear_string_option(&buf->b_p_qe);
     buf->b_p_ac = -1;
     buf->b_p_ar = -1;
+#ifdef HAVE_FSYNC
+    buf->b_p_fs = -1;
+#endif
     buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
     clear_string_option(&buf->b_p_lw);
     clear_string_option(&buf->b_p_bkc);
index 342b5f36f6f4ced44d3978c84fb07bb0830134c7..c1a495318865a6d93c50ad5243320bdca469a930 100644 (file)
@@ -2199,7 +2199,8 @@ restore_backup:
        // For a device do try the fsync() but don't complain if it does not
        // work (could be a pipe).
        // If the 'fsync' option is FALSE, don't fsync().  Useful for laptops.
-       if (p_fs && vim_fsync(fd) != 0 && !device)
+       if ((buf->b_p_fs >= 0 ? buf->b_p_fs : p_fs) && vim_fsync(fd) != 0
+               && !device)
        {
            errmsg = (char_u *)_(e_fsync_failed);
            end = 0;
index b5594dd6e3391ad2b1c5849812e3e274223bfe54..1ec7efbf83ed6de55f0131ea1be77e495e59c533 100644 (file)
@@ -698,6 +698,9 @@ set_init_1(int clean_arg)
     curbuf->b_p_initialized = TRUE;
     curbuf->b_p_ac = -1;
     curbuf->b_p_ar = -1;       // no local 'autoread' value
+#ifdef HAVE_FSYNC
+    curbuf->b_p_fs = -1;       // no local 'fsync' value
+#endif
     curbuf->b_p_ul = NO_LOCAL_UNDOLEVEL;
     check_buf_options(curbuf);
     check_win_options(curwin);
@@ -2216,6 +2219,10 @@ do_set_option_bool(
            value = -1;
        else if ((int *)varp == &curbuf->b_p_ac && opt_flags == OPT_LOCAL)
            value = -1;
+#ifdef HAVE_FSYNC
+       else if ((int *)varp == &curbuf->b_p_fs && opt_flags == OPT_LOCAL)
+           value = -1;
+#endif
        else
            value = *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL);
     }
@@ -6479,6 +6486,11 @@ unset_global_local_option(char_u *name, void *from)
        case PV_AR:
            buf->b_p_ar = -1;
            break;
+#ifdef HAVE_FSYNC
+       case PV_FS:
+           buf->b_p_fs = -1;
+           break;
+#endif
        case PV_BKC:
            clear_string_option(&buf->b_p_bkc);
            buf->b_bkc_flags = 0;
@@ -6613,6 +6625,9 @@ get_varp_scope(struct vimoption *p, int scope)
        switch ((int)p->indir)
        {
            case PV_FP:   return (char_u *)&(curbuf->b_p_fp);
+#ifdef HAVE_FSYNC
+           case PV_FS: return (char_u *)&(curbuf->b_p_fs);
+#endif
 #ifdef FEAT_EVAL
            case PV_FFU: return (char_u *)&(curbuf->b_p_ffu);
 #endif
@@ -6737,6 +6752,10 @@ get_varp(struct vimoption *p)
 #endif
        case PV_FP:     return *curbuf->b_p_fp != NUL
                                    ? (char_u *)&(curbuf->b_p_fp) : p->var;
+#ifdef HAVE_FSYNC
+       case PV_FS:     return curbuf->b_p_fs >= 0
+                                   ? (char_u *)&(curbuf->b_p_fs) : p->var;
+#endif
 #ifdef FEAT_EVAL
        case PV_FFU:    return *curbuf->b_p_ffu != NUL
                                    ? (char_u *)&(curbuf->b_p_ffu) : p->var;
@@ -7540,6 +7559,9 @@ buf_copy_options(buf_T *buf, int flags)
            // are not copied, start using the global value
            buf->b_p_ac = -1;
            buf->b_p_ar = -1;
+#ifdef HAVE_FSYNC
+           buf->b_p_fs = -1;
+#endif
            buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
            buf->b_p_bkc = empty_option;
            buf->b_bkc_flags = 0;
index f5c36ad89bd213fd22cae227a9f81feff4680005..7372ba924f353d65904566df228fba2e085e1254 100644 (file)
@@ -1223,6 +1223,9 @@ enum
     , BV_FF
     , BV_FLP
     , BV_FO
+#ifdef HAVE_FSYNC
+    , BV_FS
+#endif
     , BV_FT
     , BV_IMI
     , BV_IMS
index d888615f539d1ce914091416791036c02ffa651b..9e561247029c731ecd06cfae1e127f35719f7c89 100644 (file)
@@ -82,6 +82,9 @@
 #define PV_FF          OPT_BUF(BV_FF)
 #define PV_FLP         OPT_BUF(BV_FLP)
 #define PV_FO          OPT_BUF(BV_FO)
+#ifdef HAVE_FSYNC
+# define PV_FS         OPT_BOTH(OPT_BUF(BV_FS))
+#endif
 #define PV_FT          OPT_BUF(BV_FT)
 #define PV_IMI         OPT_BUF(BV_IMI)
 #define PV_IMS         OPT_BUF(BV_IMS)
@@ -1172,7 +1175,7 @@ static struct vimoption options[] =
                            {(char_u *)"", (char_u *)0L} SCTX_INIT},
     {"fsync",       "fs",   P_BOOL|P_SECURE|P_VI_DEF,
 #ifdef HAVE_FSYNC
-                           (char_u *)&p_fs, PV_NONE, NULL, NULL,
+                           (char_u *)&p_fs, PV_FS, NULL, NULL,
                            {(char_u *)TRUE, (char_u *)0L}
 #else
                            (char_u *)NULL, PV_NONE, NULL, NULL,
index 9b095c328ec23ca632bab89c43b846c68fcefc48..37f9cf5d18ba22a6aca623297e25f821fbe8a7c5 100644 (file)
@@ -3380,6 +3380,9 @@ struct file_buffer
     char_u     *b_p_fex;       // 'formatexpr'
     long_u     b_p_fex_flags;  // flags for 'formatexpr'
 #endif
+#ifdef HAVE_FSYNC
+    int                b_p_fs;         // 'fsync'
+#endif
 #ifdef FEAT_CRYPT
     char_u     *b_p_key;       // 'key'
 #endif
index 2e4e9f7271f509771caf0da3582f1c25caab223e..c6c83bb9863a2891fb5b173bda6fc70880b88236 100644 (file)
@@ -1681,25 +1681,34 @@ endfunc
 
 " Test for setting boolean global-local option value
 func Test_set_boolean_global_local_option()
-  setglobal autoread
-  setlocal noautoread
+  CheckUnix
+
+  setglobal autoread fsync
+  setlocal noautoread nofsync
   call assert_equal(1, &g:autoread)
   call assert_equal(0, &l:autoread)
   call assert_equal(0, &autoread)
+  call assert_equal(1, &g:fsync)
+  call assert_equal(0, &l:fsync)
+  call assert_equal(0, &fsync)
 
   " :set {option}< set the effective value of {option} to its global value.
-  set autoread<
+  set autoread< fsync<
   call assert_equal(1, &l:autoread)
   call assert_equal(1, &autoread)
+  call assert_equal(1, &l:fsync)
+  call assert_equal(1, &fsync)
 
   " :setlocal {option}< removes the local value, so that the global value will be used.
-  setglobal noautoread
-  setlocal autoread
-  setlocal autoread<
+  setglobal noautoread nofsync
+  setlocal autoread fsync
+  setlocal autoread< fsync<
   call assert_equal(-1, &l:autoread)
   call assert_equal(0, &autoread)
+  call assert_equal(-1, &l:fsync)
+  call assert_equal(0, &fsync)
 
-  set autoread&
+  set autoread& fsync&
 endfunc
 
 func Test_set_in_sandbox()
index b1747996b8e2e24b845256379fc37e1d23ea2ca1..f40aca66052f0aa5bccdb45855f31e3b2f620320 100644 (file)
@@ -1774,7 +1774,8 @@ u_write_undo(
 #endif
 
 #if defined(UNIX) && defined(HAVE_FSYNC)
-    if (p_fs && fflush(fp) == 0 && vim_fsync(fd) != 0)
+    if ((buf->b_p_fs >= 0 ? buf->b_p_fs : p_fs) && fflush(fp) == 0
+           && vim_fsync(fd) != 0)
        write_ok = FALSE;
 #endif
 
index fad0bdd585f8e8a7cbf4f76c54666e518cad092c..f09ff17915b1f7f9ae5f54366346830a0583fc90 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2024,
 /**/
     2023,
 /**/