From a32b59710fcacb439ef6ea8166a5f4bec1086f20 Mon Sep 17 00:00:00 2001 From: Julian Scheel Date: Wed, 2 Mar 2016 16:11:42 +0100 Subject: [PATCH 1/2] adapter: Fix option parsing name ended up as a unknown option due to not being part of the if/elif block. Signed-off-by: Julian Scheel --- adapter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adapter.py b/adapter.py index ee3d924..7a7e161 100644 --- a/adapter.py +++ b/adapter.py @@ -245,7 +245,7 @@ def set_options(self, options): for key in options.keys(): if key == 'name': self.setName(options[key]) - if key == 'addrFam': + elif key == 'addrFam': self.setAddrFam(options[key]) elif key == 'source': self.setAddressSource(options[key]) From 0aa2b8215b2257308fed3de20c0f20a233cf6680 Mon Sep 17 00:00:00 2001 From: Julian Scheel Date: Wed, 11 May 2016 11:08:35 +0200 Subject: [PATCH 2/2] toolutils: Fix atomic_write Using shutil.copy is not atomic. The only guaranteed atomic operation is os.rename, which requires source and target to be on the same filesystem. Ensure this by resolving the real file path in case it is symlink and place the tmp file in the same directory. Signed-off-by: Julian Scheel --- toolutils.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/toolutils.py b/toolutils.py index ab1b247..38b938b 100644 --- a/toolutils.py +++ b/toolutils.py @@ -1,6 +1,5 @@ import os import tempfile -import shutil from contextlib import contextmanager import subprocess @@ -27,9 +26,12 @@ def atomic_write(filepath): :param filepath: the file path to be opened """ - with tempfile.NamedTemporaryFile() as tf: + # Put tmp file to same directory as target file, to allow atomic move + realpath = os.path.realpath(filepath) + tmppath = os.path.dirname(realpath) + with tempfile.NamedTemporaryFile(dir=tmppath, delete=False) as tf: with open(tf.name, mode='w+') as tmp: yield tmp tmp.flush() os.fsync(tmp.fileno()) - shutil.copy(tf.name, filepath) + os.rename(tf.name, realpath)