emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/trunk r110528: Fix some stat-related races.


From: Paul Eggert
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r110528: Fix some stat-related races.
Date: Fri, 12 Oct 2012 17:52:01 -0700
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 110528
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Fri 2012-10-12 17:52:01 -0700
message:
  Fix some stat-related races.
  
  * fileio.c (Fwrite_region): Avoid race condition if a file is
  removed or renamed by some other process immediately after Emacs
  writes it but before Emacs stats it.  Do not assume that stat (or
  fstat) succeeds.
  * image.c (slurp_file): Resolve the file name with fopen + fstat
  rather than stat + fopen.
  (pbm_read_file) [0]: Remove unused code with stat race.
  * process.c (allocate_pty) [HAVE_PTYS && !PTY_ITERATION && !PTY_OPEN]:
  Remove ineffective code with stat race.
modified:
  src/ChangeLog
  src/fileio.c
  src/image.c
  src/process.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2012-10-12 20:11:50 +0000
+++ b/src/ChangeLog     2012-10-13 00:52:01 +0000
@@ -1,3 +1,16 @@
+2012-10-13  Paul Eggert  <address@hidden>
+
+       Fix some stat-related races.
+       * fileio.c (Fwrite_region): Avoid race condition if a file is
+       removed or renamed by some other process immediately after Emacs
+       writes it but before Emacs stats it.  Do not assume that stat (or
+       fstat) succeeds.
+       * image.c (slurp_file): Resolve the file name with fopen + fstat
+       rather than stat + fopen.
+       (pbm_read_file) [0]: Remove unused code with stat race.
+       * process.c (allocate_pty) [HAVE_PTYS && !PTY_ITERATION && !PTY_OPEN]:
+       Remove ineffective code with stat race.
+
 2012-10-12  Stefan Monnier  <address@hidden>
 
        * doc.c (get_doc_string): Don't signal an error if the file is missing.

=== modified file 'src/fileio.c'
--- a/src/fileio.c      2012-10-12 15:19:54 +0000
+++ b/src/fileio.c      2012-10-13 00:52:01 +0000
@@ -4545,6 +4545,7 @@
   int save_errno = 0;
   const char *fn;
   struct stat st;
+  EMACS_TIME modtime;
   ptrdiff_t count = SPECPDL_INDEX ();
   int count1;
   Lisp_Object handler;
@@ -4757,12 +4758,19 @@
     }
 #endif
 
+  modtime = invalid_emacs_time ();
+  if (visiting)
+    {
+      if (fstat (desc, &st) == 0)
+       modtime = get_stat_mtime (&st);
+      else
+       ok = 0, save_errno = errno;
+    }
+
   /* NFS can report a write failure now.  */
   if (emacs_close (desc) < 0)
     ok = 0, save_errno = errno;
 
-  stat (fn, &st);
-
   /* Discard the unwind protect for close_file_unwind.  */
   specpdl_ptr = specpdl + count1;
 
@@ -4790,9 +4798,9 @@
   /* Do this before reporting IO error
      to avoid a "file has changed on disk" warning on
      next attempt to save.  */
-  if (visiting)
+  if (EMACS_TIME_VALID_P (modtime))
     {
-      current_buffer->modtime = get_stat_mtime (&st);
+      current_buffer->modtime = modtime;
       current_buffer->modtime_size = st.st_size;
     }
 

=== modified file 'src/image.c'
--- a/src/image.c       2012-10-08 22:14:39 +0000
+++ b/src/image.c       2012-10-13 00:52:01 +0000
@@ -2140,12 +2140,11 @@
 static unsigned char *
 slurp_file (char *file, ptrdiff_t *size)
 {
-  FILE *fp = NULL;
+  FILE *fp = fopen (file, "rb");
   unsigned char *buf = NULL;
   struct stat st;
 
-  if (stat (file, &st) == 0
-      && (fp = fopen (file, "rb")) != NULL
+  if (fp && fstat (fileno (fp), &st) == 0
       && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX)
       && (buf = xmalloc (st.st_size),
          fread (buf, 1, st.st_size, fp) == st.st_size))
@@ -5004,45 +5003,6 @@
 }
 
 
-#ifdef HAVE_NTGUI
-#if 0  /* Unused. ++kfs  */
-
-/* Read FILE into memory.  Value is a pointer to a buffer allocated
-   with xmalloc holding FILE's contents.  Value is null if an error
-   occurred.  *SIZE is set to the size of the file.  */
-
-static char *
-pbm_read_file (Lisp_Object file, int *size)
-{
-  FILE *fp = NULL;
-  char *buf = NULL;
-  struct stat st;
-
-  if (stat (SDATA (file), &st) == 0
-      && (fp = fopen (SDATA (file), "rb")) != NULL
-      && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX)
-      && (buf = xmalloc (st.st_size),
-         fread (buf, 1, st.st_size, fp) == st.st_size))
-    {
-      *size = st.st_size;
-      fclose (fp);
-    }
-  else
-    {
-      if (fp)
-       fclose (fp);
-      if (buf)
-       {
-         xfree (buf);
-         buf = NULL;
-       }
-    }
-
-  return buf;
-}
-#endif
-#endif /* HAVE_NTGUI */
-
 /* Load PBM image IMG for use on frame F.  */
 
 static bool

=== modified file 'src/process.c'
--- a/src/process.c     2012-10-10 20:09:47 +0000
+++ b/src/process.c     2012-10-13 00:52:01 +0000
@@ -646,23 +646,6 @@
        PTY_OPEN;
 #else /* no PTY_OPEN */
        {
-         { /* Some systems name their pseudoterminals so that there are gaps in
-              the usual sequence - for example, on HP9000/S700 systems, there
-              are no pseudoterminals with names ending in 'f'.  So we wait for
-              three failures in a row before deciding that we've reached the
-              end of the ptys.  */
-           int failed_count = 0;
-           struct stat stb;
-
-           if (stat (pty_name, &stb) < 0)
-             {
-               failed_count++;
-               if (failed_count >= 3)
-                 return -1;
-             }
-           else
-             failed_count = 0;
-         }
 #  ifdef O_NONBLOCK
          fd = emacs_open (pty_name, O_RDWR | O_NONBLOCK, 0);
 #  else


reply via email to

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