Avoid corrupting the .sconsign.dblite file by writing to a temporary file and renamin...
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 15 Sep 2004 19:35:49 +0000 (19:35 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 15 Sep 2004 19:35:49 +0000 (19:35 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@1071 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/dblite.py

index 814107bda5dee3f2abeb66debebfe2e1b16d0933..83ec410f9e01f3cfe3c00725eebc4773a1ebd8e2 100644 (file)
@@ -30,6 +30,10 @@ RELEASE 0.97 - XXX
     SetBuildSignatureType(), SetContentSignatureType(), SetJobs() and
     GetJobs() global functions (deprecated in 0.14).
 
+  - Fix problems with corrupting the .sconsign.dblite file when
+    interrupting builds by writing to a temporary file and renaming,
+    not writing the file directly.
+
   From Gary Oberbrunner:
 
   - Add an Environment.Dump() method to print the contents of a
index c9845a751d545fce2a788d73ff42dae464f19af7..c2407ea982ee2da3d0872cbe0caf450c5a283fe9 100644 (file)
@@ -5,6 +5,7 @@ import cPickle
 import time
 import shutil
 import os
+import os.path
 import types
 import __builtin__
 
@@ -26,14 +27,22 @@ try:
 except NameError:
     def unicode(s): return s
 
+dblite_suffix = '.dblite'
+tmp_suffix = '.tmp'
+
 class dblite:
 
   def __init__(self, file_base_name, flag, mode):
     assert flag in (None, "r", "w", "c", "n")
     if (flag is None): flag = "r"
-    if file_base_name[-7:] != '.dblite':
-        file_base_name = file_base_name + '.dblite'
-    self._file_name = file_base_name
+    base, ext = os.path.splitext(file_base_name)
+    if ext == dblite_suffix:
+      # There's already a suffix on the file name, don't add one.
+      self._file_name = file_base_name
+      self._tmp_name = base + tmp_suffix
+    else:
+      self._file_name = file_base_name + dblite_suffix
+      self._tmp_name = file_base_name + tmp_suffix
     self._flag = flag
     self._mode = mode
     self._dict = {}
@@ -63,9 +72,10 @@ class dblite:
 
   def sync(self):
     self._check_writable()
-    f = _open(self._file_name, "wb", self._mode)
+    f = _open(self._tmp_name, "wb", self._mode)
     cPickle.dump(self._dict, f, 1)
     f.close()
+    os.rename(self._tmp_name, self._file_name)
     self._needs_sync = 00000
     if (keep_all_files):
       shutil.copyfile(