mercurial/util.py
changeset 1528 c9f33196805b
parent 1521 11a58d2cdffb
child 1541 bf4e7ef08741
equal deleted inserted replaced
1527:c13fce7167c2 1528:c9f33196805b
   360 
   360 
   361     this function is used to hide the details of COW semantics and
   361     this function is used to hide the details of COW semantics and
   362     remote file access from higher level code.
   362     remote file access from higher level code.
   363     """
   363     """
   364     p = base
   364     p = base
   365     def o(path, mode="r", text=False):
   365 
       
   366     def mktempcopy(name):
       
   367         d, fn = os.path.split(name)
       
   368         fd, temp = tempfile.mkstemp(prefix=fn, dir=d)
       
   369         fp = os.fdopen(fd, "wb")
       
   370         try:
       
   371             fp.write(file(name, "rb").read())
       
   372         except:
       
   373             try: os.unlink(temp)
       
   374             except: pass
       
   375             raise
       
   376         fp.close()
       
   377         st = os.lstat(name)
       
   378         os.chmod(temp, st.st_mode)
       
   379         return temp
       
   380 
       
   381     class atomicfile(file):
       
   382         """the file will only be copied on close"""
       
   383         def __init__(self, name, mode, atomic=False):
       
   384             self.__name = name
       
   385             self.temp = mktempcopy(name)
       
   386             file.__init__(self, self.temp, mode)
       
   387         def close(self):
       
   388             if not self.closed:
       
   389                 rename(self.temp, self.__name)
       
   390             file.close(self)
       
   391         def __del__(self):
       
   392             self.close()
       
   393 
       
   394     def o(path, mode="r", text=False, atomic=False):
   366         f = os.path.join(p, path)
   395         f = os.path.join(p, path)
   367 
   396 
   368         if not text:
   397         if not text:
   369             mode += "b" # for that other OS
   398             mode += "b" # for that other OS
   370 
   399 
   374             except OSError:
   403             except OSError:
   375                 d = os.path.dirname(f)
   404                 d = os.path.dirname(f)
   376                 if not os.path.isdir(d):
   405                 if not os.path.isdir(d):
   377                     os.makedirs(d)
   406                     os.makedirs(d)
   378             else:
   407             else:
       
   408                 if atomic:
       
   409                     return atomicfile(f, mode)
   379                 if nlink > 1:
   410                 if nlink > 1:
   380                     d, fn = os.path.split(f)
   411                     rename(mktempcopy(f), f)
   381                     fd, temp = tempfile.mkstemp(prefix=fn, dir=d)
       
   382                     fp = os.fdopen(fd, "wb")
       
   383                     try:
       
   384                         fp.write(file(f, "rb").read())
       
   385                     except:
       
   386                         try: os.unlink(temp)
       
   387                         except: pass
       
   388                         raise
       
   389                     fp.close()
       
   390                     st = os.lstat(f)
       
   391                     os.chmod(temp, st.st_mode)
       
   392                     rename(temp, f)
       
   393 
       
   394         return file(f, mode)
   412         return file(f, mode)
   395 
   413 
   396     return o
   414     return o
   397 
   415 
   398 def _makelock_file(info, pathname):
   416 def _makelock_file(info, pathname):