aboutsummaryrefslogtreecommitdiffstats
path: root/src/fileio.c
diff options
context:
space:
mode:
authorPaul Eggert2013-02-02 11:18:00 -0800
committerPaul Eggert2013-02-02 11:18:00 -0800
commit8ea41ea99608c7483ef5c91e230a760cf90bfb54 (patch)
treea3cb2538ecd6f106b6e55c4d4c76be1487b01431 /src/fileio.c
parente7ac588e198385a9bc5a2338000ab6db69c2353c (diff)
downloademacs-8ea41ea99608c7483ef5c91e230a760cf90bfb54.tar.gz
emacs-8ea41ea99608c7483ef5c91e230a760cf90bfb54.zip
Avoid file time stamp bug on MS-Windows.
* fileio.c (Fwrite_region): Don't use the heuristic on empty files, as FAT32 doesn't update time stamps when truncating them. Also, check that a file time stamp is not a multiple of 100 ns; this should catch all instances of the problem on MS-Windows, as its native file system resolution is 100 ns or worse, and checking for a non-multiple of 100 ns should impose only a small overhead on systems with ns resolution. Fixes: debbugs:13149
Diffstat (limited to 'src/fileio.c')
-rw-r--r--src/fileio.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/fileio.c b/src/fileio.c
index 99c5f7a5837..e76f2bc2420 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -5020,11 +5020,22 @@ This calls `write-region-annotate-functions' at the start, and
5020 if (fstat (desc1, &st1) == 0 5020 if (fstat (desc1, &st1) == 0
5021 && st.st_dev == st1.st_dev && st.st_ino == st1.st_ino) 5021 && st.st_dev == st1.st_dev && st.st_ino == st1.st_ino)
5022 { 5022 {
5023 /* Use the heuristic if it appears to be valid. With neither
5024 O_EXCL nor O_TRUNC, if Emacs happened to write nothing to the
5025 file, the time stamp won't change. Also, some non-POSIX
5026 systems don't update an empty file's time stamp when
5027 truncating it. Finally, file systems with 100 ns or worse
5028 resolution sometimes seem to have bugs: on a system with ns
5029 resolution, checking ns % 100 incorrectly avoids the heuristic
5030 1% of the time, but the problem should be temporary as we will
5031 try again on the next time stamp. */
5032 bool use_heuristic
5033 = ((open_flags & (O_EXCL | O_TRUNC)) != 0
5034 && st.st_size != 0
5035 && EMACS_NSECS (modtime) % 100 != 0);
5036
5023 EMACS_TIME modtime1 = get_stat_mtime (&st1); 5037 EMACS_TIME modtime1 = get_stat_mtime (&st1);
5024 /* If neither O_EXCL nor O_TRUNC is used, and Emacs happened to 5038 if (use_heuristic
5025 write nothing to the file, the file's time stamp won't change
5026 so it should not be used in this heuristic. */
5027 if ((open_flags & (O_EXCL | O_TRUNC)) != 0
5028 && EMACS_TIME_EQ (modtime, modtime1) 5039 && EMACS_TIME_EQ (modtime, modtime1)
5029 && st.st_size == st1.st_size) 5040 && st.st_size == st1.st_size)
5030 { 5041 {