Can't get exclusive file lock when safely renaming a file

Martin P. Hellwig martin.hellwig at dcuktec.org
Sat Dec 6 07:53:35 EST 2008


Steven D'Aprano wrote:
<cut>
> import os, fcntl
> oldname = "ham.txt"
> newname = "spam.txt"
> 
> def lock_destination(name):
>     fileno = os.open(name, os.O_CREAT | os.O_EXCL)
>     fcntl.flock(fileno, fcntl.LOCK_EX)  # POSIX systems only
>     return fileno
> 
> # Create a test file to be renamed.
> f = open(oldname, 'w')
> f.write('this is my file\n')
> f.close()
> fileno = lock_destination(newname)
> 
> # At this point, I can see "ham.txt" plus an empty file 
> # "spam.txt" in my file browser
> 
> os.rename(oldname, newname)
> 
> The rename works, but here is my problem: after getting what I thought 
> was an exclusive lock on the new file, but before calling os.rename(), I 
> can still over-write it from another process:
> 
> $ echo "this comes from another process" > spam.txt
> $ cat spam.txt
> this comes from another process
> 
<cut>
This is weird, you would indeed expect it to be locked, I tried it on 
FreeBSD and it behaves the same.
I guess the behavior of os.rename should be changed so it raises an 
exception when the source destination exists independent on the below 
platform.

I tried searching for another way to do it but the closest I came was to 
popen mv and raise an exception if it asks to overwrite the existing file.

Sorry I can't be of more help.
-- 
mph




More information about the Python-list mailing list