=== modified file 'django/core/files/move.py'
|
|
|
|
| 7 | 7 | |
| 8 | 8 | import os |
| 9 | 9 | from django.core.files import locks |
| 10 | | |
| 11 | | __all__ = ['file_move_safe'] |
| 12 | | |
| 13 | 10 | try: |
| 14 | | import shutil |
| 15 | | file_move = shutil.move |
| | 11 | from shutil import copystat |
| 16 | 12 | except ImportError: |
| 17 | | file_move = os.rename |
| | 13 | def copystat(src, dst): |
| | 14 | """Copy all stat info (mode bits, atime and mtime) from src to dst""" |
| | 15 | st = os.stat(src) |
| | 16 | mode = stat.S_IMODE(st.st_mode) |
| | 17 | if hasattr(os, 'utime'): |
| | 18 | os.utime(dst, (st.st_atime, st.st_mtime)) |
| | 19 | if hasattr(os, 'chmod'): |
| | 20 | os.chmod(dst, mode) |
| | 21 | |
| | 22 | __all__ = ['file_move_safe'] |
| | 23 | |
| | 24 | def _samefile(src, dst): |
| | 25 | # Macintosh, Unix. |
| | 26 | if hasattr(os.path,'samefile'): |
| | 27 | try: |
| | 28 | return os.path.samefile(src, dst) |
| | 29 | except OSError: |
| | 30 | return False |
| | 31 | |
| | 32 | # All other platforms: check for same pathname. |
| | 33 | return (os.path.normcase(os.path.abspath(src)) == |
| | 34 | os.path.normcase(os.path.abspath(dst))) |
| 18 | 35 | |
| 19 | 36 | def file_move_safe(old_file_name, new_file_name, chunk_size = 1024*64, allow_overwrite=False): |
| 20 | 37 | """ |
| … |
… |
|
| 30 | 47 | """ |
| 31 | 48 | |
| 32 | 49 | # There's no reason to move if we don't have to. |
| 33 | | if old_file_name == new_file_name: |
| | 50 | if _samefile(old_file_name, new_file_name): |
| 34 | 51 | return |
| 35 | 52 | |
| 36 | | if not allow_overwrite and os.path.exists(new_file_name): |
| 37 | | raise IOError("Cannot overwrite existing file '%s'." % new_file_name) |
| 38 | | |
| 39 | 53 | try: |
| 40 | | file_move(old_file_name, new_file_name) |
| | 54 | os.rename(old_file_name, new_file_name) |
| 41 | 55 | return |
| 42 | 56 | except OSError: |
| 43 | 57 | # This will happen with os.rename if moving to another filesystem |
| | 58 | # or when moving opened files on certain operating systems |
| 44 | 59 | pass |
| 45 | 60 | |
| 46 | | # If the built-in didn't work, do it the hard way. |
| 47 | | fd = os.open(new_file_name, os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, 'O_BINARY', 0)) |
| | 61 | # first open the old file, so that it won't go away |
| | 62 | old_file = open(old_file_name, 'rb') |
| 48 | 63 | try: |
| 49 | | locks.lock(fd, locks.LOCK_EX) |
| 50 | | old_file = open(old_file_name, 'rb') |
| 51 | | current_chunk = None |
| 52 | | while current_chunk != '': |
| 53 | | current_chunk = old_file.read(chunk_size) |
| 54 | | os.write(fd, current_chunk) |
| | 64 | # now open the new file, not forgetting allow_overwrite |
| | 65 | fd = os.open(new_file_name, os.O_WRONLY | os.O_CREAT | getattr(os, 'O_BINARY', 0) | |
| | 66 | (not allow_overwrite and os.O_EXCL or 0)) |
| | 67 | try: |
| | 68 | locks.lock(fd, locks.LOCK_EX) |
| | 69 | current_chunk = None |
| | 70 | while current_chunk != '': |
| | 71 | current_chunk = old_file.read(chunk_size) |
| | 72 | os.write(fd, current_chunk) |
| | 73 | finally: |
| | 74 | locks.unlock(fd) |
| | 75 | os.close(fd) |
| 55 | 76 | finally: |
| 56 | | locks.unlock(fd) |
| 57 | | os.close(fd) |
| 58 | 77 | old_file.close() |
| | 78 | copystat(old_file_name, new_file_name) |
| 59 | 79 | |
| 60 | | os.remove(old_file_name) |
| | 80 | try: |
| | 81 | os.remove(old_file_name) |
| | 82 | except OSError, e: |
| | 83 | # Certain operating systems (Cygwin and Windows) |
| | 84 | # fail when deleting opened files, ignore it |
| | 85 | if getattr(e, 'winerror', 0) != 32: |
| | 86 | # FIXME: should we also ignore errno 13? |
| | 87 | raise |
=== modified file 'django/core/files/temp.py'
|
|
|
|
| 25 | 25 | fd, name = tempfile.mkstemp(suffix=suffix, prefix=prefix, |
| 26 | 26 | dir=dir) |
| 27 | 27 | self.name = name |
| 28 | | self._file = os.fdopen(fd, mode, bufsize) |
| | 28 | self.file = os.fdopen(fd, mode, bufsize) |
| | 29 | self.close_called = False |
| | 30 | |
| | 31 | # Because close can be called during shutdown |
| | 32 | # we need to cache os.unlink and access it |
| | 33 | # as self.unlink only |
| | 34 | unlink = os.unlink |
| | 35 | |
| | 36 | def close(self): |
| | 37 | if not self.close_called: |
| | 38 | self.close_called = True |
| | 39 | try: |
| | 40 | self.file.close() |
| | 41 | except (OSError, IOError): |
| | 42 | pass |
| | 43 | try: |
| | 44 | self.unlink(self.name) |
| | 45 | except (OSError): |
| | 46 | pass |
| 29 | 47 | |
| 30 | 48 | def __del__(self): |
| 31 | | try: |
| 32 | | self._file.close() |
| 33 | | except (OSError, IOError): |
| 34 | | pass |
| 35 | | try: |
| 36 | | os.unlink(self.name) |
| 37 | | except (OSError): |
| 38 | | pass |
| 39 | | |
| 40 | | try: |
| 41 | | super(TemporaryFile, self).__del__() |
| 42 | | except AttributeError: |
| 43 | | pass |
| 44 | | |
| 45 | | |
| 46 | | def read(self, *args): return self._file.read(*args) |
| 47 | | def seek(self, offset): return self._file.seek(offset) |
| 48 | | def write(self, s): return self._file.write(s) |
| 49 | | def close(self): return self._file.close() |
| 50 | | def __iter__(self): return iter(self._file) |
| 51 | | def readlines(self, size=None): return self._file.readlines(size) |
| 52 | | def xreadlines(self): return self._file.xreadlines() |
| | 49 | self.close() |
| | 50 | |
| | 51 | def read(self, *args): return self.file.read(*args) |
| | 52 | def seek(self, offset): return self.file.seek(offset) |
| | 53 | def write(self, s): return self.file.write(s) |
| | 54 | def __iter__(self): return iter(self.file) |
| | 55 | def readlines(self, size=None): return self.file.readlines(size) |
| | 56 | def xreadlines(self): return self.file.xreadlines() |
| 53 | 57 | |
| 54 | 58 | NamedTemporaryFile = TemporaryFile |
| 55 | 59 | else: |
=== modified file 'tests/regressiontests/file_uploads/views.py'
|
|
|
|
| 2 | 2 | from django.core.files.uploadedfile import UploadedFile |
| 3 | 3 | from django.http import HttpResponse, HttpResponseServerError |
| 4 | 4 | from django.utils import simplejson |
| | 5 | from models import FileModel |
| 5 | 6 | from uploadhandler import QuotaUploadHandler |
| 6 | 7 | from django.utils.hashcompat import sha_constructor |
| 7 | 8 | |
| … |
… |
|
| 45 | 46 | if new_hash != submitted_hash: |
| 46 | 47 | return HttpResponseServerError() |
| 47 | 48 | |
| | 49 | # Adding large file to the database should succeed |
| | 50 | largefile = request.FILES['file_field2'] |
| | 51 | obj = FileModel() |
| | 52 | obj.testfile.save(largefile.name, largefile) |
| | 53 | |
| 48 | 54 | return HttpResponse('') |
| 49 | 55 | |
| 50 | 56 | def file_upload_echo(request): |