comparison mercurial/util.py @ 1528:c9f33196805b

add an atomic argument to util.opener when atomic is used, the file while be renamed on close
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Fri, 11 Nov 2005 15:33:59 -0800
parents 11a58d2cdffb
children bf4e7ef08741
comparison
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):