diff options
author | Jacob Kaplan-Moss <jacob@jacobian.org> | 2008-08-11 16:51:18 +0000 |
---|---|---|
committer | Jacob Kaplan-Moss <jacob@jacobian.org> | 2008-08-11 16:51:18 +0000 |
commit | 58cd4902a71a3695dd6c21dc957f59c333db364c (patch) | |
tree | 3af68e7cfb7ad5cbb3e46c4d242f73262e11c99d /django/core/files/move.py | |
parent | ab1a442a01eb3ee1ca210cd689c9b578d31d7366 (diff) | |
download | django-58cd4902a71a3695dd6c21dc957f59c333db364c.tar.gz |
Fixed #4948, a race condition in file saving. Thanks to Martin von Löwis, who diagnosed the problem and pointed the way to a fix.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8306 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/core/files/move.py')
-rw-r--r-- | django/core/files/move.py | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/django/core/files/move.py b/django/core/files/move.py index 66873d450c..5ae776c3dd 100644 --- a/django/core/files/move.py +++ b/django/core/files/move.py @@ -44,16 +44,17 @@ def file_move_safe(old_file_name, new_file_name, chunk_size = 1024*64, allow_ove pass # If the built-in didn't work, do it the hard way. - new_file = open(new_file_name, 'wb') - locks.lock(new_file, locks.LOCK_EX) - old_file = open(old_file_name, 'rb') - current_chunk = None - - while current_chunk != '': - current_chunk = old_file.read(chunk_size) - new_file.write(current_chunk) - - new_file.close() - old_file.close() + fd = os.open(new_file_name, os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, 'O_BINARY', 0)) + try: + locks.lock(fd, locks.LOCK_EX) + old_file = open(old_file_name, 'rb') + current_chunk = None + while current_chunk != '': + current_chunk = old_file.read(chunk_size) + os.write(fd, current_chunk) + finally: + locks.unlock(fd) + os.close(fd) + old_file.close() os.remove(old_file_name) |