Show More
@@ -630,13 +630,28 b' def rename(src, dst):' | |||
|
630 | 630 | try: |
|
631 | 631 | os.rename(src, dst) |
|
632 | 632 | except OSError, err: # FIXME: check err (EEXIST ?) |
|
633 | # on windows, rename to existing file is not allowed, so we | |
|
634 | # must delete destination first. but if file is open, unlink | |
|
635 | # schedules it for delete but does not delete it. rename | |
|
633 | ||
|
634 | # On windows, rename to existing file is not allowed, so we | |
|
635 | # must delete destination first. But if a file is open, unlink | |
|
636 | # schedules it for delete but does not delete it. Rename | |
|
636 | 637 | # happens immediately even for open files, so we rename |
|
637 |
# destination to a temporary name, then delete that. |
|
|
638 | # destination to a temporary name, then delete that. Then | |
|
638 | 639 | # rename is safe to do. |
|
639 | temp = dst + "-force-rename" | |
|
640 | # The temporary name is chosen at random to avoid the situation | |
|
641 | # where a file is left lying around from a previous aborted run. | |
|
642 | # The usual race condition this introduces can't be avoided as | |
|
643 | # we need the name to rename into, and not the file itself. Due | |
|
644 | # to the nature of the operation however, any races will at worst | |
|
645 | # lead to the rename failing and the current operation aborting. | |
|
646 | ||
|
647 | def tempname(prefix): | |
|
648 | for tries in xrange(10): | |
|
649 | temp = '%s-%08x' % (prefix, random.randint(0, 0xffffffff)) | |
|
650 | if not os.path.exists(temp): | |
|
651 | return temp | |
|
652 | raise IOError, (errno.EEXIST, "No usable temporary filename found") | |
|
653 | ||
|
654 | temp = tempname(dst) | |
|
640 | 655 | os.rename(dst, temp) |
|
641 | 656 | os.unlink(temp) |
|
642 | 657 | os.rename(src, dst) |
General Comments 0
You need to be logged in to leave comments.
Login now