[Python-checkins] cpython (3.3): #19037: adjust file times *before* moving maildir files into place.

r.david.murray python-checkins at python.org
Wed Sep 18 14:39:33 CEST 2013


http://hg.python.org/cpython/rev/68e5e416e8af
changeset:   85746:68e5e416e8af
branch:      3.3
parent:      85743:abb68583a47f
user:        R David Murray <rdmurray at bitdance.com>
date:        Wed Sep 18 08:34:40 2013 -0400
summary:
  #19037: adjust file times *before* moving maildir files into place.

This avoids race conditions when other programs are monitoring
the maildir directory.  Patch by janzert.

files:
  Lib/mailbox.py |  18 +++++++++++++-----
  Misc/NEWS      |   4 ++++
  2 files changed, 17 insertions(+), 5 deletions(-)


diff --git a/Lib/mailbox.py b/Lib/mailbox.py
--- a/Lib/mailbox.py
+++ b/Lib/mailbox.py
@@ -311,6 +311,12 @@
             suffix = ''
         uniq = os.path.basename(tmp_file.name).split(self.colon)[0]
         dest = os.path.join(self._path, subdir, uniq + suffix)
+        if isinstance(message, MaildirMessage):
+            os.utime(tmp_file.name,
+                     (os.path.getatime(tmp_file.name), message.get_date()))
+        # No file modification should be done after the file is moved to its
+        # final position in order to prevent race conditions with changes
+        # from other programs
         try:
             if hasattr(os, 'link'):
                 os.link(tmp_file.name, dest)
@@ -324,8 +330,6 @@
                                          % dest)
             else:
                 raise
-        if isinstance(message, MaildirMessage):
-            os.utime(dest, (os.path.getatime(dest), message.get_date()))
         return uniq
 
     def remove(self, key):
@@ -360,11 +364,15 @@
         else:
             suffix = ''
         self.discard(key)
+        tmp_path = os.path.join(self._path, temp_subpath)
         new_path = os.path.join(self._path, subdir, key + suffix)
-        os.rename(os.path.join(self._path, temp_subpath), new_path)
         if isinstance(message, MaildirMessage):
-            os.utime(new_path, (os.path.getatime(new_path),
-                                message.get_date()))
+            os.utime(tmp_path,
+                     (os.path.getatime(tmp_path), message.get_date()))
+        # No file modification should be done after the file is moved to its
+        # final position in order to prevent race conditions with changes
+        # from other programs
+        os.rename(tmp_path, new_path)
 
     def get_message(self, key):
         """Return a Message representation or raise a KeyError."""
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -68,6 +68,10 @@
 Library
 -------
 
+- Issue #19037: The mailbox module now makes all changes to maildir files
+  before moving them into place, to avoid race conditions with other programs
+  that may be accessing the maildir directory.
+
 - Issue #14984: On POSIX systems, when netrc is called without a filename
   argument (and therefore is reading the user's $HOME/.netrc file), it now
   enforces the same security rules as typical ftp clients: the .netrc file must

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list