My understanding of os.O_EXCL is that it locks the file from changes by any other process.  It appears from a quick test, though, that this is not the case. Perhaps the second suggestion in the linked thread (using link/unlink) would work better, since this situation only arises on unix.<div>
<br></div><div>I like the idea of a context manager for locking, but I'm not sure how that would work in this case...<br><br><div class="gmail_quote">On Fri, Aug 12, 2011 at 3:53 PM, Devin Jeanpierre <span dir="ltr"><<a href="mailto:jeanpierreda@gmail.com">jeanpierreda@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">This doesn't completely solve the race condition:<br>
<br>
`os.open(path, O_EXCL | O_CREAT)` opens an fd for a file location. If<br>
a file was already at that location, it fails, if not, it succeeds<br>
with an fd.<br>
So if os.move() used this fd to actually write the new data, there<br>
would be no race condition in terms of file creation/deletion. This<br>
is, as far as I can tell, what was suggested by your linked thread.<br>
<br>
However, in your suggestion it does not do that: it does opens a new<br>
fd to a new file, and then does precisely what it did before. During<br>
the time in-between the os.open and the shutil.move(), somebody can<br>
delete the created file, and write a new one, or whatever. If they do<br>
that, then any such changes they make will be lost because shutil.move<br>
will steamroller them and overwrite the file.<br>
<font color="#888888"><br>
Devin<br>
</font><div class="im"><br>
On Fri, Aug 12, 2011 at 7:59 AM, David Townshend <<a href="mailto:aquavitae69@gmail.com">aquavitae69@gmail.com</a>> wrote:<br>
</div><div><div></div><div class="h5">> The shutil.move function uses os.rename to move files on the same file<br>
> system. On unix, this function will overwrite an existing destination, so<br>
> the obvious approach is<br>
> if not os.path.exists(dst):<br>
>     shutil.move(src, dst)<br>
> But this could result in race conditions if dst is created after<br>
> os.path.exists and before shutil.move.  From my research, it seems that this<br>
> is a limitation in the unix c library, but it should be possible to avoid it<br>
> through a workaround (pieced together<br>
> from <a href="http://bytes.com/topic/python/answers/555794-safely-renaming-file-without-overwriting" target="_blank">http://bytes.com/topic/python/answers/555794-safely-renaming-file-without-overwriting</a>).<br>
>  This involves some fairly low-level work, so I propose adding a new move2<br>
> function to shutil, which raises an error if dst exists and locking it if it<br>
> doesn't:<br>
> def move2(src, dst):<br>
>     try:<br>
>         fd = os.open(dst, os.O_EXCL | os.O_CREAT)<br>
>     except OSError:<br>
>         raise Error('Destination exists')<br>
>     try:<br>
>         move(src, dst)<br>
>     finally:<br>
>         os.close(fd)<br>
> This could be optimised by using shutil.move code rather than just calling<br>
> it, but the idea is that an attempt is made to create dst with exclusive<br>
> access. If this fails, then it means that the file exists, but if it passes,<br>
> then dst is locked so no other process can create it.<br>
</div></div><div><div></div><div class="h5">> _______________________________________________<br>
> Python-ideas mailing list<br>
> <a href="mailto:Python-ideas@python.org">Python-ideas@python.org</a><br>
> <a href="http://mail.python.org/mailman/listinfo/python-ideas" target="_blank">http://mail.python.org/mailman/listinfo/python-ideas</a><br>
><br>
><br>
</div></div></blockquote></div><br></div>