bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: diff-2.7.7 crashes on /proc/<pid>/maps


From: Paul Eggert
Subject: Re: diff-2.7.7 crashes on /proc/<pid>/maps
Date: Wed, 30 Jan 2002 17:22:50 -0800 (PST)

> From: Bruno Haible <address@hidden>
> Date: Wed, 30 Jan 2002 14:59:02 +0100 (CET)

> Question: Is GNU diff right in assuming that the file contains no more
> bytes than its size says?

No.  Though I believe POSIX says the results are undefined in this
situation, GNU diff obviously shouldn't dump core anyway.

I can't reproduce your problem on my GNU/Linux box, no doubt because
my /proc/*/maps files are still named pipes.  So please try the
following patch; I've tested it by hand in a simulated environment but
of course it's better to try it on the real thing.

2002-01-30  Paul Eggert  <address@hidden>

        * src/io.c (slurp): Don't dump core if an input regular file
        grows while 'diff' is reading it.  Bug reported by Bruno Haible.

--- src/io.c    2002/01/24 20:16:38     1.23
+++ src/io.c    2002/01/31 01:15:01
@@ -153,7 +153,10 @@ slurp (struct file_data *current)
 
   if (current->desc < 0)
-    /* The file is nonexistent.  */
-    ;
-  else if (S_ISREG (current->stat.st_mode))
+    {
+      /* The file is nonexistent.  */
+      return;
+    }
+
+  if (S_ISREG (current->stat.st_mode))
     {
       /* It's a regular file; slurp in the rest all at once.  */
@@ -173,29 +176,37 @@ slurp (struct file_data *current)
        }
 
-      if (current->buffered < file_size)
-       file_block_read (current, file_size - current->buffered);
-    }
-  /* It's not a regular file; read it, growing the buffer as needed.  */
-  else
-    {
-      file_block_read (current, current->bufsize - current->buffered);
+      /* Try to read at least 1 more byte than the size indicates, to
+        detect whether the file is growing.  This is a nicety for
+        users who run 'diff' on files while they are changing.  */
 
-      if (current->buffered)
+      if (current->buffered <= file_size)
        {
-         while (current->buffered == current->bufsize)
-           {
-             if (2 * current->bufsize < current->bufsize)
-               xalloc_die ();
-             current->bufsize *= 2;
-             current->buffer = xrealloc (current->buffer, current->bufsize);
-             file_block_read (current, current->bufsize - current->buffered);
-           }
+         file_block_read (current, file_size + 1 - current->buffered);
+         if (current->buffered <= file_size)
+           return;
+       }
+    }
+
+  /* It's not a regular file, or it's a growing regular file; read it,
+     growing the buffer as needed.  */
+
+  file_block_read (current, current->bufsize - current->buffered);
 
-         /* Allocate just enough room for appended newline plus word
-            sentinel, plus word-alignment.  */
-         cc = current->buffered + 2 * sizeof (word);
-         current->bufsize = cc - cc % sizeof (word);
+  if (current->buffered)
+    {
+      while (current->buffered == current->bufsize)
+       {
+         if (2 * current->bufsize < current->bufsize)
+           xalloc_die ();
+         current->bufsize *= 2;
          current->buffer = xrealloc (current->buffer, current->bufsize);
+         file_block_read (current, current->bufsize - current->buffered);
        }
+
+      /* Allocate just enough room for appended newline plus word
+        sentinel, plus word-alignment.  */
+      cc = current->buffered + 2 * sizeof (word);
+      current->bufsize = cc - cc % sizeof (word);
+      current->buffer = xrealloc (current->buffer, current->bufsize);
     }
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]