diff options
| author | Paul Eggert | 2013-02-02 11:18:00 -0800 |
|---|---|---|
| committer | Paul Eggert | 2013-02-02 11:18:00 -0800 |
| commit | 8ea41ea99608c7483ef5c91e230a760cf90bfb54 (patch) | |
| tree | a3cb2538ecd6f106b6e55c4d4c76be1487b01431 /src | |
| parent | e7ac588e198385a9bc5a2338000ab6db69c2353c (diff) | |
| download | emacs-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')
| -rw-r--r-- | src/ChangeLog | 11 | ||||
| -rw-r--r-- | src/fileio.c | 19 |
2 files changed, 26 insertions, 4 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index b90f18eba91..092302d6492 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,14 @@ | |||
| 1 | 2013-02-02 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Avoid file time stamp bug on MS-Windows (Bug#13149). | ||
| 4 | * fileio.c (Fwrite_region): Don't use the heuristic on empty files, | ||
| 5 | as FAT32 doesn't update time stamps when truncating them. | ||
| 6 | Also, check that a file time stamp is not a multiple of 100 ns; | ||
| 7 | this should catch all instances of the problem on MS-Windows, | ||
| 8 | as its native file system resolution is 100 ns or worse, and | ||
| 9 | checking for a non-multiple of 100 ns should impose only a small | ||
| 10 | overhead on systems with ns resolution. | ||
| 11 | |||
| 1 | 2013-02-02 Eli Zaretskii <eliz@gnu.org> | 12 | 2013-02-02 Eli Zaretskii <eliz@gnu.org> |
| 2 | 13 | ||
| 3 | Avoid encoding file names on MS-Windows when they need to be run | 14 | Avoid encoding file names on MS-Windows when they need to be run |
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 | { |