diff options
author | Marko Kreen | 2012-06-15 13:32:06 +0000 |
---|---|---|
committer | Marko Kreen | 2012-06-15 13:32:06 +0000 |
commit | c51a6dc989a9882cb91bbfe2927cd3cedb2d506a (patch) | |
tree | 018fd920cc4f41d602bba6eced4313098f28ed5a /python/skytools/fileutil.py | |
parent | 8b4c4cd42abab87181c46802945078ffd8ab2e21 (diff) |
skytools.fileutil: new module, contains write_atomic()
Diffstat (limited to 'python/skytools/fileutil.py')
-rw-r--r-- | python/skytools/fileutil.py | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/python/skytools/fileutil.py b/python/skytools/fileutil.py new file mode 100644 index 00000000..fd657fd4 --- /dev/null +++ b/python/skytools/fileutil.py @@ -0,0 +1,37 @@ +"""File utilities""" + +import os + +__all__ = ['write_atomic'] + +def write_atomic(fn, data, bakext=None, mode='b'): + """Write file with rename.""" + + if mode not in ['', 'b', 't']: + raise ValueError("unsupported fopen mode") + + # write new data to tmp file + fn2 = fn + '.new' + f = open(fn2, 'w' + mode) + f.write(data) + f.close() + + # link old data to bak file + if bakext: + if bakext.find('/') >= 0: + raise ValueError("invalid bakext") + fnb = fn + bakext + try: + os.unlink(fnb) + except OSError, e: + if e.errno != errno.ENOENT: + raise + try: + os.link(fn, fnb) + except OSError, e: + if e.errno != errno.ENOENT: + raise + + # atomically replace file + os.rename(fn2, fn) + |