Patch 8.2.3510
Problem:    Changes are only detected with one second accuracy.
Solution:   Use the nanosecond time if possible.  (Leah Neukirchen,
            closes #8873, closes #8875)
Files:      runtime/doc/eval.txt, src/auto/configure, src/bufwrite.c,
            src/config.h.in, src/configure.ac, src/fileio.c,
            src/proto/fileio.pro, src/memline.c, src/netbeans.c,
            src/structs.h, src/evalfunc.c, src/testdir/test_stat.vim


*** ../vim-8.2.3509/runtime/doc/eval.txt        2021-10-03 15:19:09.821731156 
+0100
--- runtime/doc/eval.txt        2021-10-14 21:21:28.989308890 +0100
***************
*** 12126,12131 ****
--- 12236,12242 ----
  multi_byte_ime                Compiled with support for IME input method.
  multi_lang            Compiled with support for multiple languages.
  mzscheme              Compiled with MzScheme interface |mzscheme|.
+ nanotime              Compiled with sub-second time stamp checks.
  netbeans_enabled      Compiled with support for |netbeans| and connected.
  netbeans_intg         Compiled with support for |netbeans|.
  num64                 Compiled with 64-bit |Number| support.
*** ../vim-8.2.3509/src/auto/configure  2021-10-06 11:27:17.766745946 +0100
--- src/auto/configure  2021-10-14 20:48:16.658560510 +0100
***************
*** 13149,13154 ****
--- 13149,13200 ----
  
  fi
  
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nanoseconds field of 
struct stat" >&5
+ $as_echo_n "checking for nanoseconds field of struct stat... " >&6; }
+ if ${ac_cv_struct_st_mtim_nsec+:} false; then :
+   $as_echo_n "(cached) " >&6
+ else
+   ac_save_CPPFLAGS="$CPPFLAGS"
+    ac_cv_struct_st_mtim_nsec=no
+    # st_mtim.tv_nsec -- the usual case
+    # st_mtim._tv_nsec -- Solaris 2.6, if
+    #  (defined _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED == 1
+    #   && !defined __EXTENSIONS__)
+    # st_mtim.st__tim.tv_nsec -- UnixWare 2.1.2
+    # st_mtime_n -- AIX 5.2 and above
+    # st_mtimespec.tv_nsec -- Darwin (Mac OSX)
+    for ac_val in st_mtim.tv_nsec st_mtim._tv_nsec st_mtim.st__tim.tv_nsec 
st_mtime_n st_mtimespec.tv_nsec; do
+      CPPFLAGS="$ac_save_CPPFLAGS -DST_MTIM_NSEC=$ac_val"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ int
+ main ()
+ {
+ struct stat s; s.ST_MTIM_NSEC;
+   ;
+   return 0;
+ }
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+   ac_cv_struct_st_mtim_nsec=$ac_val; break
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    done
+    CPPFLAGS="$ac_save_CPPFLAGS"
+ 
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_st_mtim_nsec" 
>&5
+ $as_echo "$ac_cv_struct_st_mtim_nsec" >&6; }
+ if test $ac_cv_struct_st_mtim_nsec != no; then
+ 
+ cat >>confdefs.h <<_ACEOF
+ #define ST_MTIM_NSEC $ac_cv_struct_st_mtim_nsec
+ _ACEOF
+ 
+ fi
+ 
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv_open()" >&5
  $as_echo_n "checking for iconv_open()... " >&6; }
  save_LIBS="$LIBS"
*** ../vim-8.2.3509/src/bufwrite.c      2021-07-25 13:36:01.565551200 +0100
--- src/bufwrite.c      2021-10-14 21:11:12.884960869 +0100
***************
*** 527,533 ****
  check_mtime(buf_T *buf, stat_T *st)
  {
      if (buf->b_mtime_read != 0
!           && time_differs((long)st->st_mtime, buf->b_mtime_read))
      {
        msg_scroll = TRUE;          // don't overwrite messages here
        msg_silent = 0;             // must give this prompt
--- 527,533 ----
  check_mtime(buf_T *buf, stat_T *st)
  {
      if (buf->b_mtime_read != 0
!                 && time_differs(st, buf->b_mtime_read, buf->b_mtime_read_ns))
      {
        msg_scroll = TRUE;          // don't overwrite messages here
        msg_silent = 0;             // must give this prompt
***************
*** 2558,2563 ****
--- 2558,2564 ----
            {
                buf_store_time(buf, &st_old, fname);
                buf->b_mtime_read = buf->b_mtime;
+               buf->b_mtime_read_ns = buf->b_mtime_ns;
            }
        }
      }
*** ../vim-8.2.3509/src/config.h.in     2021-06-20 13:01:25.980924619 +0100
--- src/config.h.in     2021-10-14 20:43:53.623758080 +0100
***************
*** 144,149 ****
--- 144,152 ----
  /* Define if stat() ignores a trailing slash */
  #undef STAT_IGNORES_SLASH
  
+ /* Define to nanoseconds field of struct stat */
+ #undef ST_MTIM_NSEC
+ 
  /* Define if tgetstr() has a second argument that is (char *) */
  #undef TGETSTR_CHAR_P
  
*** ../vim-8.2.3509/src/configure.ac    2021-10-06 11:27:17.766745946 +0100
--- src/configure.ac    2021-10-14 20:43:53.627758121 +0100
***************
*** 3843,3848 ****
--- 3843,3873 ----
  if test "x$vim_cv_stat_ignores_slash" = "xyes" ; then
    AC_DEFINE(STAT_IGNORES_SLASH)
  fi
+ 
+ dnl nanoseconds field of struct stat
+ AC_CACHE_CHECK([for nanoseconds field of struct stat],
+   ac_cv_struct_st_mtim_nsec,
+   [ac_save_CPPFLAGS="$CPPFLAGS"
+    ac_cv_struct_st_mtim_nsec=no
+    # st_mtim.tv_nsec -- the usual case
+    # st_mtim._tv_nsec -- Solaris 2.6, if
+    #  (defined _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED == 1
+    #   && !defined __EXTENSIONS__)
+    # st_mtim.st__tim.tv_nsec -- UnixWare 2.1.2
+    # st_mtime_n -- AIX 5.2 and above
+    # st_mtimespec.tv_nsec -- Darwin (Mac OSX)
+    for ac_val in st_mtim.tv_nsec st_mtim._tv_nsec st_mtim.st__tim.tv_nsec 
st_mtime_n st_mtimespec.tv_nsec; do
+      CPPFLAGS="$ac_save_CPPFLAGS -DST_MTIM_NSEC=$ac_val"
+      AC_TRY_COMPILE([#include <sys/types.h>
+ #include <sys/stat.h>], [struct stat s; s.ST_MTIM_NSEC;],
+        [ac_cv_struct_st_mtim_nsec=$ac_val; break])
+    done
+    CPPFLAGS="$ac_save_CPPFLAGS"
+ ])
+ if test $ac_cv_struct_st_mtim_nsec != no; then
+   AC_DEFINE_UNQUOTED([ST_MTIM_NSEC], [$ac_cv_struct_st_mtim_nsec],
+   [Define if struct stat contains a nanoseconds field])
+ fi
    
  dnl Link with iconv for charset translation, if not found without library.
  dnl check for iconv() requires including iconv.h
*** ../vim-8.2.3509/src/fileio.c        2021-09-22 13:18:09.313222517 +0100
--- src/fileio.c        2021-10-14 21:26:43.421387665 +0100
***************
*** 408,413 ****
--- 408,414 ----
        {
            buf_store_time(curbuf, &st, fname);
            curbuf->b_mtime_read = curbuf->b_mtime;
+           curbuf->b_mtime_read_ns = curbuf->b_mtime_ns;
            filesize_disk = st.st_size;
  #ifdef UNIX
            /*
***************
*** 432,438 ****
--- 433,441 ----
        else
        {
            curbuf->b_mtime = 0;
+           curbuf->b_mtime_ns = 0;
            curbuf->b_mtime_read = 0;
+           curbuf->b_mtime_read_ns = 0;
            curbuf->b_orig_size = 0;
            curbuf->b_orig_mode = 0;
        }
***************
*** 2569,2574 ****
--- 2572,2578 ----
        {
            buf_store_time(curbuf, &st, fname);
            curbuf->b_mtime_read = curbuf->b_mtime;
+           curbuf->b_mtime_read_ns = curbuf->b_mtime_ns;
        }
  #endif
      }
***************
*** 3115,3129 ****
  }
  
      int
! time_differs(long t1, long t2)
  {
  #if defined(__linux__) || defined(MSWIN)
      // On a FAT filesystem, esp. under Linux, there are only 5 bits to store
      // the seconds.  Since the roundoff is done when flushing the inode, the
      // time may change unexpectedly by one second!!!
!     return (t1 - t2 > 1 || t2 - t1 > 1);
  #else
!     return (t1 != t2);
  #endif
  }
  
--- 3119,3137 ----
  }
  
      int
! time_differs(stat_T *st, long mtime, long mtime_ns UNUSED)
  {
  #if defined(__linux__) || defined(MSWIN)
      // On a FAT filesystem, esp. under Linux, there are only 5 bits to store
      // the seconds.  Since the roundoff is done when flushing the inode, the
      // time may change unexpectedly by one second!!!
!     return (long)st->st_mtime - mtime > 1 || mtime - (long)st->st_mtime > 1
! # ifdef ST_MTIM_NSEC
!               || (long)st->ST_MTIM_NSEC != mtime_ns
! # endif
!               ;
  #else
!     return (long)st->st_mtime != mtime;
  #endif
  }
  
***************
*** 4072,4078 ****
      if (       !(buf->b_flags & BF_NOTEDITED)
            && buf->b_mtime != 0
            && ((stat_res = mch_stat((char *)buf->b_ffname, &st)) < 0
!               || time_differs((long)st.st_mtime, buf->b_mtime)
                || st.st_size != buf->b_orig_size
  #ifdef HAVE_ST_MODE
                || (int)st.st_mode != buf->b_orig_mode
--- 4080,4086 ----
      if (       !(buf->b_flags & BF_NOTEDITED)
            && buf->b_mtime != 0
            && ((stat_res = mch_stat((char *)buf->b_ffname, &st)) < 0
!               || time_differs(&st, buf->b_mtime, buf->b_mtime_ns)
                || st.st_size != buf->b_orig_size
  #ifdef HAVE_ST_MODE
                || (int)st.st_mode != buf->b_orig_mode
***************
*** 4187,4195 ****
--- 4195,4206 ----
                        mesg2 = _("See \":help W16\" for more info.");
                    }
                    else
+                   {
                        // Only timestamp changed, store it to avoid a warning
                        // in check_mtime() later.
                        buf->b_mtime_read = buf->b_mtime;
+                       buf->b_mtime_read_ns = buf->b_mtime_ns;
+                   }
                }
            }
        }
***************
*** 4468,4473 ****
--- 4479,4489 ----
  buf_store_time(buf_T *buf, stat_T *st, char_u *fname UNUSED)
  {
      buf->b_mtime = (long)st->st_mtime;
+ #ifdef ST_MTIM_NSEC
+     buf->b_mtime_ns = (long)st->ST_MTIM_NSEC;
+ #else
+     buf->b_mtime_ns = 0;
+ #endif
      buf->b_orig_size = st->st_size;
  #ifdef HAVE_ST_MODE
      buf->b_orig_mode = (int)st->st_mode;
*** ../vim-8.2.3509/src/proto/fileio.pro        2020-06-16 19:03:38.747351038 
+0100
--- src/proto/fileio.pro        2021-10-14 21:10:48.108607390 +0100
***************
*** 12,18 ****
  int msg_add_fileformat(int eol_type);
  void msg_add_lines(int insert_space, long lnum, off_T nchars);
  void msg_add_eol(void);
! int time_differs(long t1, long t2);
  int need_conversion(char_u *fenc);
  int get_fio_flags(char_u *ptr);
  int get_win_fio_flags(char_u *ptr);
--- 12,18 ----
  int msg_add_fileformat(int eol_type);
  void msg_add_lines(int insert_space, long lnum, off_T nchars);
  void msg_add_eol(void);
! int time_differs(stat_T *st, long mtime, long mtime_ns);
  int need_conversion(char_u *fenc);
  int get_fio_flags(char_u *ptr);
  int get_win_fio_flags(char_u *ptr);
*** ../vim-8.2.3509/src/memline.c       2021-10-09 15:39:20.459884353 +0100
--- src/memline.c       2021-10-14 20:43:53.627758121 +0100
***************
*** 1032,1037 ****
--- 1032,1038 ----
  #endif
            buf_store_time(buf, &st, buf->b_ffname);
            buf->b_mtime_read = buf->b_mtime;
+           buf->b_mtime_read_ns = buf->b_mtime_ns;
        }
        else
        {
***************
*** 1040,1046 ****
--- 1041,1049 ----
            long_to_char(0L, b0p->b0_ino);
  #endif
            buf->b_mtime = 0;
+           buf->b_mtime_ns = 0;
            buf->b_mtime_read = 0;
+           buf->b_mtime_read_ns = 0;
            buf->b_orig_size = 0;
            buf->b_orig_mode = 0;
        }
***************
*** 2436,2441 ****
--- 2439,2447 ----
             */
            if (mch_stat((char *)buf->b_ffname, &st) == -1
                    || st.st_mtime != buf->b_mtime_read
+ #ifdef ST_MTIM_NSEC
+                   || st.ST_MTIM_NSEC != buf->b_mtime_read_ns
+ #endif
                    || st.st_size != buf->b_orig_size)
            {
                ml_preserve(buf, FALSE);
*** ../vim-8.2.3509/src/netbeans.c      2021-08-02 17:07:15.186473836 +0100
--- src/netbeans.c      2021-10-14 20:43:53.627758121 +0100
***************
*** 1760,1766 ****
--- 1760,1769 ----
            if (buf == NULL || buf->bufp == NULL)
                nbdebug(("    invalid buffer identifier in setModtime\n"));
            else
+           {
                buf->bufp->b_mtime = atoi((char *)args);
+               buf->bufp->b_mtime_ns = 0;
+           }
  // =====================================================================
        }
        else if (streq((char *)cmd, "setReadOnly"))
*** ../vim-8.2.3509/src/structs.h       2021-10-05 19:44:00.859799210 +0100
--- src/structs.h       2021-10-14 20:43:53.627758121 +0100
***************
*** 2724,2730 ****
--- 2724,2732 ----
      wininfo_T *b_wininfo;     // list of last used info for each window
  
      long      b_mtime;        // last change time of original file
+     long      b_mtime_ns;     // nanoseconds of last change time
      long      b_mtime_read;   // last change time when reading
+     long      b_mtime_read_ns;  // nanoseconds of last read time
      off_T     b_orig_size;    // size of original file in bytes
      int               b_orig_mode;    // mode of original file
  #ifdef FEAT_VIMINFO
*** ../vim-8.2.3509/src/evalfunc.c      2021-09-26 19:03:59.662298673 +0100
--- src/evalfunc.c      2021-10-14 21:18:54.039267277 +0100
***************
*** 5479,5484 ****
--- 5479,5491 ----
                0
  #endif
                },
+       {"nanotime",
+ #ifdef ST_MTIM_NSEC
+               1
+ #else
+               0
+ #endif
+       },
        {"num64", 1},
        {"ole",
  #ifdef FEAT_OLE
*** ../vim-8.2.3509/src/testdir/test_stat.vim   2020-08-12 17:50:31.887655765 
+0100
--- src/testdir/test_stat.vim   2021-10-14 21:20:10.928283676 +0100
***************
*** 76,81 ****
--- 76,114 ----
    call delete(fname)
  endfunc
  
+ func Test_checktime_fast()
+   CheckFeature nanotime
+ 
+   let fname = 'Xtest.tmp'
+ 
+   let fl = ['Hello World!']
+   call writefile(fl, fname)
+   set autoread
+   exec 'e' fname
+   let fl = readfile(fname)
+   let fl[0] .= ' - checktime'
+   call writefile(fl, fname)
+   checktime
+   call assert_equal(fl[0], getline(1))
+ 
+   call delete(fname)
+ endfunc
+ 
+ func Test_autoread_fast()
+   CheckFeature nanotime
+ 
+   new Xautoread
+   set autoread
+   call setline(1, 'foo')
+ 
+   w!
+   silent !echo bar > Xautoread
+   checktime
+ 
+   call assert_equal('bar', trim(getline(1)))
+   call delete('Xautoread')
+ endfunc
+ 
  func Test_autoread_file_deleted()
    new Xautoread
    set autoread
*** ../vim-8.2.3509/src/version.c       2021-10-14 17:52:19.016102283 +0100
--- src/version.c       2021-10-14 20:47:59.966381260 +0100
***************
*** 759,760 ****
--- 759,762 ----
  {   /* Add new patch number below this line */
+ /**/
+     3510,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
153. You find yourself staring at your "inbox" waiting for new e-mail
     to arrive.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20211014212633.E8AD8C80053%40moolenaar.net.

Raspunde prin e-mail lui