mercurial/util.py
changeset 4336 1cc5fc1d0994
parent 4309 d4f0405fadac
parent 4331 ce52deed83bc
child 4338 8b4d4f84b739
--- a/mercurial/util.py	Sat Apr 07 04:45:27 2007 -0300
+++ b/mercurial/util.py	Mon Apr 09 04:57:25 2007 -0300
@@ -804,6 +804,9 @@
         return lambda x: os.path.islink(os.path.join(path, x))
     return fallback
 
+_umask = os.umask(0)
+os.umask(_umask)
+
 # Platform specific variants
 if os.name == 'nt':
     import msvcrt
@@ -930,8 +933,6 @@
 
 else:
     nulldev = '/dev/null'
-    _umask = os.umask(0)
-    os.umask(_umask)
 
     def rcfiles(path):
         rcs = [os.path.join(path, 'hgrc')]
@@ -1103,18 +1104,32 @@
     p = base
     audit_p = audit
 
-    def mktempcopy(name):
+    def mktempcopy(name, emptyok=False):
         d, fn = os.path.split(name)
         fd, temp = tempfile.mkstemp(prefix='.%s-' % fn, dir=d)
         os.close(fd)
-        ofp = posixfile(temp, "wb")
+        # Temporary files are created with mode 0600, which is usually not
+        # what we want.  If the original file already exists, just copy
+        # its mode.  Otherwise, manually obey umask.
+        try:
+            st_mode = os.lstat(name).st_mode
+        except OSError, inst:
+            if inst.errno != errno.ENOENT:
+                raise
+            st_mode = 0666 & ~_umask
+        os.chmod(temp, st_mode)
+        if emptyok:
+            return temp
         try:
             try:
                 ifp = posixfile(name, "rb")
             except IOError, inst:
+                if inst.errno == errno.ENOENT:
+                    return temp
                 if not getattr(inst, 'filename', None):
                     inst.filename = name
                 raise
+            ofp = posixfile(temp, "wb")
             for chunk in filechunkiter(ifp):
                 ofp.write(chunk)
             ifp.close()
@@ -1123,15 +1138,13 @@
             try: os.unlink(temp)
             except: pass
             raise
-        st = os.lstat(name)
-        os.chmod(temp, st.st_mode)
         return temp
 
     class atomictempfile(posixfile):
         """the file will only be copied when rename is called"""
         def __init__(self, name, mode):
             self.__name = name
-            self.temp = mktempcopy(name)
+            self.temp = mktempcopy(name, emptyok=('w' in mode))
             posixfile.__init__(self, self.temp, mode)
         def rename(self):
             if not self.closed:
@@ -1165,16 +1178,16 @@
             try:
                 nlink = nlinks(f)
             except OSError:
+                nlink = 0
                 d = os.path.dirname(f)
                 if not os.path.isdir(d):
                     os.makedirs(d)
-            else:
-                if atomic:
-                    return atomicfile(f, mode)
-                elif atomictemp:
-                    return atomictempfile(f, mode)
-                if nlink > 1:
-                    rename(mktempcopy(f), f)
+            if atomic:
+                return atomicfile(f, mode)
+            elif atomictemp:
+                return atomictempfile(f, mode)
+            if nlink > 1:
+                rename(mktempcopy(f), f)
         return posixfile(f, mode)
 
     return o