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.
This commit is contained in:
Stefan Monnier 2010-04-12 21:47:40 -04:00
parent 5b31b787b7
commit 58b963f7f3
4 changed files with 38 additions and 8 deletions

View file

@ -1,3 +1,13 @@
2010-04-13 Stefan Monnier <monnier@iro.umontreal.ca>
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.
2010-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
* process.c (status_notify): Remove unused var `ro'.

View file

@ -693,6 +693,7 @@ reset_buffer (b)
b->file_truename = Qnil;
b->directory = (current_buffer) ? current_buffer->directory : Qnil;
b->modtime = 0;
b->modtime_size = -1;
XSETFASTINT (b->save_length, 0);
b->last_window_start = 1;
/* It is more conservative to start out "changed" than "unchanged". */

View file

@ -513,6 +513,12 @@ struct buffer
0 means visited file modtime unknown; in no case complain
about any mismatch on next save attempt. */
int modtime;
/* Size of the file when modtime was set. This is used to detect the
case where the file grew while we were reading it, so the modtime
is still the same (since it's rounded up to seconds) but we're actually
not up-to-date. -1 means the size is unknown. Only meaningful if
modtime is actually set. */
EMACS_INT modtime_size;
/* The value of text->modiff at the last auto-save. */
int auto_save_modified;
/* The value of text->modiff at the last display error.

View file

@ -4092,6 +4092,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
if (NILP (handler))
{
current_buffer->modtime = st.st_mtime;
current_buffer->modtime_size = st.st_size;
current_buffer->filename = orig_filename;
}
@ -4695,7 +4696,10 @@ This calls `write-region-annotate-functions' at the start, and
to avoid a "file has changed on disk" warning on
next attempt to save. */
if (visiting)
current_buffer->modtime = st.st_mtime;
{
current_buffer->modtime = st.st_mtime;
current_buffer->modtime_size = st.st_size;
}
if (failure)
error ("IO error writing %s: %s", SDATA (filename),
@ -5004,11 +5008,13 @@ See Info node `(elisp)Modification Time' for more details. */)
else
st.st_mtime = 0;
}
if (st.st_mtime == b->modtime
/* If both are positive, accept them if they are off by one second. */
|| (st.st_mtime > 0 && b->modtime > 0
&& (st.st_mtime == b->modtime + 1
|| st.st_mtime == b->modtime - 1)))
if ((st.st_mtime == b->modtime
/* If both are positive, accept them if they are off by one second. */
|| (st.st_mtime > 0 && b->modtime > 0
&& (st.st_mtime == b->modtime + 1
|| st.st_mtime == b->modtime - 1)))
&& (st.st_size == b->modtime_size
|| b->modtime_size < 0))
return Qt;
return Qnil;
}
@ -5020,6 +5026,7 @@ Next attempt to save will certainly not complain of a discrepancy. */)
()
{
current_buffer->modtime = 0;
current_buffer->modtime_size = -1;
return Qnil;
}
@ -5049,7 +5056,10 @@ An argument specifies the modification time value to use
Lisp_Object time_list;
{
if (!NILP (time_list))
current_buffer->modtime = cons_to_long (time_list);
{
current_buffer->modtime = cons_to_long (time_list);
current_buffer->modtime_size = -1;
}
else
{
register Lisp_Object filename;
@ -5068,7 +5078,10 @@ An argument specifies the modification time value to use
filename = ENCODE_FILE (filename);
if (stat (SDATA (filename), &st) >= 0)
current_buffer->modtime = st.st_mtime;
{
current_buffer->modtime = st.st_mtime;
current_buffer->modtime_size = st.st_size;
}
}
return Qnil;