Peter Otten writes: > Steve D'Aprano wrote: > >> On Mon, 30 Jan 2017 03:33 pm, Cameron Simpson wrote: >> >>> On 30Jan2017 13:49, Steve D'Aprano <steve+pyt...@pearwood.info> wrote: >>>>This code contains a Time Of Check to Time Of Use bug: >>>> >>>> if os.path.exists(destination) >>>> raise ValueError('destination already exists') >>>> os.rename(oldname, destination) >>>> >>>> >>>>In the microsecond between checking for the existence of the destination >>>>and actually doing the rename, it is possible that another process may >>>>create the destination, resulting in data loss. >>>> >>>>Apart from keeping my fingers crossed, how should I fix this TOCTOU bug? >>> >>> For files this is a problem at the Python level. At the UNIX level you >>> can play neat games with open(2) and the various O_* modes. >>> >>> however, with directories things are more cut and dry. Do you have much >>> freedom here? What's the wider context of the question? >> >> The wider context is that I'm taking from 1 to <arbitrarily huge number> >> path names to existing files as arguments, and for each path name I >> transfer the file name part (but not the directory part) and then rename >> the file. For example: >> >> foo/bar/baz/spam.txt >> >> may be renamed to: >> >> foo/bar/baz/ham.txt >> >> but only provided ham.txt doesn't already exist. > > Google finds > > http://stackoverflow.com/questions/3222341/how-to-rename-without-race-conditions > > and from a quick test it appears to work on Linux:
It doesn't seem to be documented. I looked at help(os.link) on Python 3.4 and the corresponding current library documentation on the web. I saw no mention of what happens when dst exists already. Also, creating a hard link doesn't seem to work between different file systems, which may well be relevant to Steve's case. I get: OSError: [Errno 18] Invalid cross-device link: [snip] And that also is not mentioned in the docs. -- https://mail.python.org/mailman/listinfo/python-list