From c51a6dc989a9882cb91bbfe2927cd3cedb2d506a Mon Sep 17 00:00:00 2001 From: Marko Kreen Date: Fri, 15 Jun 2012 16:32:06 +0300 Subject: skytools.fileutil: new module, contains write_atomic() --- python/skytools/fileutil.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 python/skytools/fileutil.py (limited to 'python/skytools/fileutil.py') 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) + -- cgit v1.2.3