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 | |
parent | 8b4c4cd42abab87181c46802945078ffd8ab2e21 (diff) |
skytools.fileutil: new module, contains write_atomic()
-rw-r--r-- | python/skytools/__init__.py | 2 | ||||
-rw-r--r-- | python/skytools/fileutil.py | 37 |
2 files changed, 39 insertions, 0 deletions
diff --git a/python/skytools/__init__.py b/python/skytools/__init__.py index 6bdeb51e..4f6d1bde 100644 --- a/python/skytools/__init__.py +++ b/python/skytools/__init__.py @@ -29,6 +29,8 @@ _symbols = { 'T_SEQUENCE': 'skytools.dbstruct:T_SEQUENCE', 'T_TABLE': 'skytools.dbstruct:T_TABLE', 'T_TRIGGER': 'skytools.dbstruct:T_TRIGGER', + # skytools.fileutil + 'write_atomic': 'skytools.fileutil:write_atomic', # skytools.gzlog 'gzip_append': 'skytools.gzlog:gzip_append', # skytools.parsing 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) + |