diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -804,6 +804,9 @@ def linkfunc(path, fallback): 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 @@ if os.name == 'nt': else: nulldev = '/dev/null' - _umask = os.umask(0) - os.umask(_umask) def rcfiles(path): rcs = [os.path.join(path, 'hgrc')] @@ -1103,18 +1104,32 @@ def opener(base, audit=True): 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 @@ def opener(base, audit=True): 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 @@ def opener(base, audit=True): 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