comparison src/fileio.c @ 25953:d7e1cf30728c v8.2.3510

patch 8.2.3510: changes are only detected with one second accuracy Commit: https://github.com/vim/vim/commit/0a7984af5601323fae7b3398f05a48087db7b767 Author: Leah Neukirchen <leah@vuxu.org> Date: Thu Oct 14 21:27:55 2021 +0100 patch 8.2.3510: changes are only detected with one second accuracy Problem: Changes are only detected with one second accuracy. Solution: Use the nanosecond time if possible. (Leah Neukirchen, closes #8873, closes #8875)
author Bram Moolenaar <Bram@vim.org>
date Thu, 14 Oct 2021 22:30:04 +0200
parents 15fe946b1a41
children aaec2028c8fc
comparison
equal deleted inserted replaced
25952:7eded0585ee0 25953:d7e1cf30728c
406 // Remember time of file. 406 // Remember time of file.
407 if (mch_stat((char *)fname, &st) >= 0) 407 if (mch_stat((char *)fname, &st) >= 0)
408 { 408 {
409 buf_store_time(curbuf, &st, fname); 409 buf_store_time(curbuf, &st, fname);
410 curbuf->b_mtime_read = curbuf->b_mtime; 410 curbuf->b_mtime_read = curbuf->b_mtime;
411 curbuf->b_mtime_read_ns = curbuf->b_mtime_ns;
411 filesize_disk = st.st_size; 412 filesize_disk = st.st_size;
412 #ifdef UNIX 413 #ifdef UNIX
413 /* 414 /*
414 * Use the protection bits of the original file for the swap file. 415 * Use the protection bits of the original file for the swap file.
415 * This makes it possible for others to read the name of the 416 * This makes it possible for others to read the name of the
430 #endif 431 #endif
431 } 432 }
432 else 433 else
433 { 434 {
434 curbuf->b_mtime = 0; 435 curbuf->b_mtime = 0;
436 curbuf->b_mtime_ns = 0;
435 curbuf->b_mtime_read = 0; 437 curbuf->b_mtime_read = 0;
438 curbuf->b_mtime_read_ns = 0;
436 curbuf->b_orig_size = 0; 439 curbuf->b_orig_size = 0;
437 curbuf->b_orig_mode = 0; 440 curbuf->b_orig_mode = 0;
438 } 441 }
439 442
440 // Reset the "new file" flag. It will be set again below when the 443 // Reset the "new file" flag. It will be set again below when the
2567 if (newfile && !read_stdin && !read_buffer 2570 if (newfile && !read_stdin && !read_buffer
2568 && mch_stat((char *)fname, &st) >= 0) 2571 && mch_stat((char *)fname, &st) >= 0)
2569 { 2572 {
2570 buf_store_time(curbuf, &st, fname); 2573 buf_store_time(curbuf, &st, fname);
2571 curbuf->b_mtime_read = curbuf->b_mtime; 2574 curbuf->b_mtime_read = curbuf->b_mtime;
2575 curbuf->b_mtime_read_ns = curbuf->b_mtime_ns;
2572 } 2576 }
2573 #endif 2577 #endif
2574 } 2578 }
2575 msg_scroll = msg_save; 2579 msg_scroll = msg_save;
2576 2580
3113 { 3117 {
3114 STRCAT(IObuff, shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]")); 3118 STRCAT(IObuff, shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]"));
3115 } 3119 }
3116 3120
3117 int 3121 int
3118 time_differs(long t1, long t2) 3122 time_differs(stat_T *st, long mtime, long mtime_ns UNUSED)
3119 { 3123 {
3120 #if defined(__linux__) || defined(MSWIN) 3124 #if defined(__linux__) || defined(MSWIN)
3121 // On a FAT filesystem, esp. under Linux, there are only 5 bits to store 3125 // On a FAT filesystem, esp. under Linux, there are only 5 bits to store
3122 // the seconds. Since the roundoff is done when flushing the inode, the 3126 // the seconds. Since the roundoff is done when flushing the inode, the
3123 // time may change unexpectedly by one second!!! 3127 // time may change unexpectedly by one second!!!
3124 return (t1 - t2 > 1 || t2 - t1 > 1); 3128 return (long)st->st_mtime - mtime > 1 || mtime - (long)st->st_mtime > 1
3129 # ifdef ST_MTIM_NSEC
3130 || (long)st->ST_MTIM_NSEC != mtime_ns
3131 # endif
3132 ;
3125 #else 3133 #else
3126 return (t1 != t2); 3134 return (long)st->st_mtime != mtime;
3127 #endif 3135 #endif
3128 } 3136 }
3129 3137
3130 /* 3138 /*
3131 * Return TRUE if file encoding "fenc" requires conversion from or to 3139 * Return TRUE if file encoding "fenc" requires conversion from or to
4070 return 0; 4078 return 0;
4071 4079
4072 if ( !(buf->b_flags & BF_NOTEDITED) 4080 if ( !(buf->b_flags & BF_NOTEDITED)
4073 && buf->b_mtime != 0 4081 && buf->b_mtime != 0
4074 && ((stat_res = mch_stat((char *)buf->b_ffname, &st)) < 0 4082 && ((stat_res = mch_stat((char *)buf->b_ffname, &st)) < 0
4075 || time_differs((long)st.st_mtime, buf->b_mtime) 4083 || time_differs(&st, buf->b_mtime, buf->b_mtime_ns)
4076 || st.st_size != buf->b_orig_size 4084 || st.st_size != buf->b_orig_size
4077 #ifdef HAVE_ST_MODE 4085 #ifdef HAVE_ST_MODE
4078 || (int)st.st_mode != buf->b_orig_mode 4086 || (int)st.st_mode != buf->b_orig_mode
4079 #else 4087 #else
4080 || mch_getperm(buf->b_ffname) != buf->b_orig_mode 4088 || mch_getperm(buf->b_ffname) != buf->b_orig_mode
4185 { 4193 {
4186 mesg = _("W16: Warning: Mode of file \"%s\" has changed since editing started"); 4194 mesg = _("W16: Warning: Mode of file \"%s\" has changed since editing started");
4187 mesg2 = _("See \":help W16\" for more info."); 4195 mesg2 = _("See \":help W16\" for more info.");
4188 } 4196 }
4189 else 4197 else
4198 {
4190 // Only timestamp changed, store it to avoid a warning 4199 // Only timestamp changed, store it to avoid a warning
4191 // in check_mtime() later. 4200 // in check_mtime() later.
4192 buf->b_mtime_read = buf->b_mtime; 4201 buf->b_mtime_read = buf->b_mtime;
4202 buf->b_mtime_read_ns = buf->b_mtime_ns;
4203 }
4193 } 4204 }
4194 } 4205 }
4195 } 4206 }
4196 4207
4197 } 4208 }
4466 4477
4467 void 4478 void
4468 buf_store_time(buf_T *buf, stat_T *st, char_u *fname UNUSED) 4479 buf_store_time(buf_T *buf, stat_T *st, char_u *fname UNUSED)
4469 { 4480 {
4470 buf->b_mtime = (long)st->st_mtime; 4481 buf->b_mtime = (long)st->st_mtime;
4482 #ifdef ST_MTIM_NSEC
4483 buf->b_mtime_ns = (long)st->ST_MTIM_NSEC;
4484 #else
4485 buf->b_mtime_ns = 0;
4486 #endif
4471 buf->b_orig_size = st->st_size; 4487 buf->b_orig_size = st->st_size;
4472 #ifdef HAVE_ST_MODE 4488 #ifdef HAVE_ST_MODE
4473 buf->b_orig_mode = (int)st->st_mode; 4489 buf->b_orig_mode = (int)st->st_mode;
4474 #else 4490 #else
4475 buf->b_orig_mode = mch_getperm(fname); 4491 buf->b_orig_mode = mch_getperm(fname);