diff options
| author | Stefan Monnier | 2010-04-12 21:47:40 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2010-04-12 21:47:40 -0400 |
| commit | 58b963f7f3d9d8e869408666608c05f3c69a5cb5 (patch) | |
| tree | 40dfbee49634c6d8b0ffd38ef1b5db86a7544ff8 /src | |
| parent | 5b31b787b743ecc6d2e7454a57deaf12ca312f01 (diff) | |
| download | emacs-58b963f7f3d9d8e869408666608c05f3c69a5cb5.tar.gz emacs-58b963f7f3d9d8e869408666608c05f3c69a5cb5.zip | |
Try to detect file modification within the same second.
* buffer.h (struct buffer): New field modtime_size.
* buffer.c (reset_buffer): Initialize it.
* fileio.c (Finsert_file_contents, Fwrite_region): Set it.
(Fverify_visited_file_modtime): Check it.
(Fclear_visited_file_modtime, Fset_visited_file_modtime): Clear it.
(Fset_visited_file_modtime): Set (or clear) it.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 10 | ||||
| -rw-r--r-- | src/buffer.c | 1 | ||||
| -rw-r--r-- | src/buffer.h | 6 | ||||
| -rw-r--r-- | src/fileio.c | 29 |
4 files changed, 38 insertions, 8 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 2c768be4821..ad88dc8311b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | 2010-04-13 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | Try to detect file modification within the same second. | ||
| 4 | * buffer.h (struct buffer): New field modtime_size. | ||
| 5 | * buffer.c (reset_buffer): Initialize it. | ||
| 6 | * fileio.c (Finsert_file_contents, Fwrite_region): Set it. | ||
| 7 | (Fverify_visited_file_modtime): Check it. | ||
| 8 | (Fclear_visited_file_modtime, Fset_visited_file_modtime): Clear it. | ||
| 9 | (Fset_visited_file_modtime): Set (or clear) it. | ||
| 10 | |||
| 1 | 2010-04-12 Stefan Monnier <monnier@iro.umontreal.ca> | 11 | 2010-04-12 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 12 | ||
| 3 | * process.c (status_notify): Remove unused var `ro'. | 13 | * process.c (status_notify): Remove unused var `ro'. |
diff --git a/src/buffer.c b/src/buffer.c index 9035a986b4c..0759ce1c43c 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -693,6 +693,7 @@ reset_buffer (b) | |||
| 693 | b->file_truename = Qnil; | 693 | b->file_truename = Qnil; |
| 694 | b->directory = (current_buffer) ? current_buffer->directory : Qnil; | 694 | b->directory = (current_buffer) ? current_buffer->directory : Qnil; |
| 695 | b->modtime = 0; | 695 | b->modtime = 0; |
| 696 | b->modtime_size = -1; | ||
| 696 | XSETFASTINT (b->save_length, 0); | 697 | XSETFASTINT (b->save_length, 0); |
| 697 | b->last_window_start = 1; | 698 | b->last_window_start = 1; |
| 698 | /* It is more conservative to start out "changed" than "unchanged". */ | 699 | /* It is more conservative to start out "changed" than "unchanged". */ |
diff --git a/src/buffer.h b/src/buffer.h index 40f03daca90..fa3fc6dafb8 100644 --- a/src/buffer.h +++ b/src/buffer.h | |||
| @@ -513,6 +513,12 @@ struct buffer | |||
| 513 | 0 means visited file modtime unknown; in no case complain | 513 | 0 means visited file modtime unknown; in no case complain |
| 514 | about any mismatch on next save attempt. */ | 514 | about any mismatch on next save attempt. */ |
| 515 | int modtime; | 515 | int modtime; |
| 516 | /* Size of the file when modtime was set. This is used to detect the | ||
| 517 | case where the file grew while we were reading it, so the modtime | ||
| 518 | is still the same (since it's rounded up to seconds) but we're actually | ||
| 519 | not up-to-date. -1 means the size is unknown. Only meaningful if | ||
| 520 | modtime is actually set. */ | ||
| 521 | EMACS_INT modtime_size; | ||
| 516 | /* The value of text->modiff at the last auto-save. */ | 522 | /* The value of text->modiff at the last auto-save. */ |
| 517 | int auto_save_modified; | 523 | int auto_save_modified; |
| 518 | /* The value of text->modiff at the last display error. | 524 | /* The value of text->modiff at the last display error. |
diff --git a/src/fileio.c b/src/fileio.c index c62d5724eff..e9440adabe0 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -4092,6 +4092,7 @@ variable `last-coding-system-used' to the coding system actually used. */) | |||
| 4092 | if (NILP (handler)) | 4092 | if (NILP (handler)) |
| 4093 | { | 4093 | { |
| 4094 | current_buffer->modtime = st.st_mtime; | 4094 | current_buffer->modtime = st.st_mtime; |
| 4095 | current_buffer->modtime_size = st.st_size; | ||
| 4095 | current_buffer->filename = orig_filename; | 4096 | current_buffer->filename = orig_filename; |
| 4096 | } | 4097 | } |
| 4097 | 4098 | ||
| @@ -4695,7 +4696,10 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4695 | to avoid a "file has changed on disk" warning on | 4696 | to avoid a "file has changed on disk" warning on |
| 4696 | next attempt to save. */ | 4697 | next attempt to save. */ |
| 4697 | if (visiting) | 4698 | if (visiting) |
| 4698 | current_buffer->modtime = st.st_mtime; | 4699 | { |
| 4700 | current_buffer->modtime = st.st_mtime; | ||
| 4701 | current_buffer->modtime_size = st.st_size; | ||
| 4702 | } | ||
| 4699 | 4703 | ||
| 4700 | if (failure) | 4704 | if (failure) |
| 4701 | error ("IO error writing %s: %s", SDATA (filename), | 4705 | error ("IO error writing %s: %s", SDATA (filename), |
| @@ -5004,11 +5008,13 @@ See Info node `(elisp)Modification Time' for more details. */) | |||
| 5004 | else | 5008 | else |
| 5005 | st.st_mtime = 0; | 5009 | st.st_mtime = 0; |
| 5006 | } | 5010 | } |
| 5007 | if (st.st_mtime == b->modtime | 5011 | if ((st.st_mtime == b->modtime |
| 5008 | /* If both are positive, accept them if they are off by one second. */ | 5012 | /* If both are positive, accept them if they are off by one second. */ |
| 5009 | || (st.st_mtime > 0 && b->modtime > 0 | 5013 | || (st.st_mtime > 0 && b->modtime > 0 |
| 5010 | && (st.st_mtime == b->modtime + 1 | 5014 | && (st.st_mtime == b->modtime + 1 |
| 5011 | || st.st_mtime == b->modtime - 1))) | 5015 | || st.st_mtime == b->modtime - 1))) |
| 5016 | && (st.st_size == b->modtime_size | ||
| 5017 | || b->modtime_size < 0)) | ||
| 5012 | return Qt; | 5018 | return Qt; |
| 5013 | return Qnil; | 5019 | return Qnil; |
| 5014 | } | 5020 | } |
| @@ -5020,6 +5026,7 @@ Next attempt to save will certainly not complain of a discrepancy. */) | |||
| 5020 | () | 5026 | () |
| 5021 | { | 5027 | { |
| 5022 | current_buffer->modtime = 0; | 5028 | current_buffer->modtime = 0; |
| 5029 | current_buffer->modtime_size = -1; | ||
| 5023 | return Qnil; | 5030 | return Qnil; |
| 5024 | } | 5031 | } |
| 5025 | 5032 | ||
| @@ -5049,7 +5056,10 @@ An argument specifies the modification time value to use | |||
| 5049 | Lisp_Object time_list; | 5056 | Lisp_Object time_list; |
| 5050 | { | 5057 | { |
| 5051 | if (!NILP (time_list)) | 5058 | if (!NILP (time_list)) |
| 5052 | current_buffer->modtime = cons_to_long (time_list); | 5059 | { |
| 5060 | current_buffer->modtime = cons_to_long (time_list); | ||
| 5061 | current_buffer->modtime_size = -1; | ||
| 5062 | } | ||
| 5053 | else | 5063 | else |
| 5054 | { | 5064 | { |
| 5055 | register Lisp_Object filename; | 5065 | register Lisp_Object filename; |
| @@ -5068,7 +5078,10 @@ An argument specifies the modification time value to use | |||
| 5068 | filename = ENCODE_FILE (filename); | 5078 | filename = ENCODE_FILE (filename); |
| 5069 | 5079 | ||
| 5070 | if (stat (SDATA (filename), &st) >= 0) | 5080 | if (stat (SDATA (filename), &st) >= 0) |
| 5071 | current_buffer->modtime = st.st_mtime; | 5081 | { |
| 5082 | current_buffer->modtime = st.st_mtime; | ||
| 5083 | current_buffer->modtime_size = st.st_size; | ||
| 5084 | } | ||
| 5072 | } | 5085 | } |
| 5073 | 5086 | ||
| 5074 | return Qnil; | 5087 | return Qnil; |