changeset 107845:688679bd79f5

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.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Mon, 12 Apr 2010 21:47:40 -0400
parents 17333bba44b4
children e8ea73860300
files src/ChangeLog src/buffer.c src/buffer.h src/fileio.c
diffstat 4 files changed, 38 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Mon Apr 12 21:24:10 2010 -0400
+++ b/src/ChangeLog	Mon Apr 12 21:47:40 2010 -0400
@@ -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'.
--- a/src/buffer.c	Mon Apr 12 21:24:10 2010 -0400
+++ b/src/buffer.c	Mon Apr 12 21:47:40 2010 -0400
@@ -693,6 +693,7 @@
   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".  */
--- a/src/buffer.h	Mon Apr 12 21:24:10 2010 -0400
+++ b/src/buffer.h	Mon Apr 12 21:47:40 2010 -0400
@@ -513,6 +513,12 @@
      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.
--- a/src/fileio.c	Mon Apr 12 21:24:10 2010 -0400
+++ b/src/fileio.c	Mon Apr 12 21:47:40 2010 -0400
@@ -4092,6 +4092,7 @@
       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 @@
      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 @@
       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 @@
      ()
 {
   current_buffer->modtime = 0;
+  current_buffer->modtime_size = -1;
   return Qnil;
 }
 
@@ -5049,7 +5056,10 @@
      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 @@
       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;