I have a file which I'm atomically replacing in Python, while trying to persistently retain a lock.
(Yes, I'm well aware that this will wreak havoc on any other programs waiting for a lock on the file unless they check for the directory entry pointing to a new inode after they actually receive their lock; that check is happening in practice).
import os, os.path, tempfile, fcntl
def replace_file(f, new_text):
f_dir = os.path.dirname(f.name)
with tempfile.NamedTemporaryFile(dir=f_dir) as temp_file:
temp_file.write(new_text)
temp_file.flush()
os.fsync(temp_file.fileno())
dest_file = os.fdopen(os.dup(temp_file.fileno()), 'r+b')
fcntl.flock(dest_file.fileno(), fcntl.LOCK_EX)
os.rename(temp_file.name, f.name)
temp_file.delete = False
# ...and after more paranoia, like fsync()ing the directory it's in...
return dest_file
f = open('/tmp/foo', 'w')
f = replace_file(f, "new string")
print f.name # name is <fdup>, not /tmp/foo
I'm hard-pressed to find a workaround for this that doesn't involve dropping the lock even temporarily after the rename has taken place.