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): |