diff options
Diffstat (limited to 'xlators/features/marker/utils/syncdaemon/syncdutils.py')
-rw-r--r-- | xlators/features/marker/utils/syncdaemon/syncdutils.py | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/xlators/features/marker/utils/syncdaemon/syncdutils.py b/xlators/features/marker/utils/syncdaemon/syncdutils.py index 52dad8c5ff3..723ab8fb5fc 100644 --- a/xlators/features/marker/utils/syncdaemon/syncdutils.py +++ b/xlators/features/marker/utils/syncdaemon/syncdutils.py @@ -1,3 +1,5 @@ +import os +import fcntl try: # py 3 from urllib import parse as urllib @@ -9,3 +11,32 @@ def escape(s): def unescape(s): return urllib.unquote_plus(s) + +def update_file(path, updater, merger = lambda f: True): + """update a file in a transaction-like manner""" + + fr = fw = None + try: + fd = os.open(path, os.O_CREAT|os.O_RDWR) + try: + fr = os.fdopen(fd, 'r+b') + except: + os.close(fd) + raise + fcntl.lockf(fr, fcntl.LOCK_EX) + merger(fr) + + tmpp = path + '.tmp.' + str(os.getpid()) + fd = os.open(tmpp, os.O_CREAT|os.O_EXCL|os.O_WRONLY) + try: + fw = os.fdopen(fd, 'wb', 0) + except: + os.close(fd) + raise + updater(fw) + os.fsync(fd) + os.rename(tmpp, path) + finally: + for fx in (fr, fw): + if fx: + fx.close() |