5 # This software may be used and distributed according to the terms of the |
5 # This software may be used and distributed according to the terms of the |
6 # GNU General Public License version 2, incorporated herein by reference. |
6 # GNU General Public License version 2, incorporated herein by reference. |
7 |
7 |
8 from i18n import _ |
8 from i18n import _ |
9 import osutil, error |
9 import osutil, error |
10 import errno, msvcrt, os, re, sys |
10 import errno, msvcrt, os, re, sys, random |
11 |
11 |
12 nulldev = 'NUL:' |
12 nulldev = 'NUL:' |
13 umask = 002 |
13 umask = 002 |
14 |
14 |
15 # wrap osutil.posixfile to provide friendlier exceptions |
15 # wrap osutil.posixfile to provide friendlier exceptions |
281 try: |
281 try: |
282 _removedirs(os.path.dirname(f)) |
282 _removedirs(os.path.dirname(f)) |
283 except OSError: |
283 except OSError: |
284 pass |
284 pass |
285 |
285 |
|
286 def rename(src, dst): |
|
287 '''atomically rename file src to dst, replacing dst if it exists''' |
|
288 try: |
|
289 os.rename(src, dst) |
|
290 except OSError, err: # FIXME: check err (EEXIST ?) |
|
291 |
|
292 # On windows, rename to existing file is not allowed, so we |
|
293 # must delete destination first. But if a file is open, unlink |
|
294 # schedules it for delete but does not delete it. Rename |
|
295 # happens immediately even for open files, so we rename |
|
296 # destination to a temporary name, then delete that. Then |
|
297 # rename is safe to do. |
|
298 # The temporary name is chosen at random to avoid the situation |
|
299 # where a file is left lying around from a previous aborted run. |
|
300 # The usual race condition this introduces can't be avoided as |
|
301 # we need the name to rename into, and not the file itself. Due |
|
302 # to the nature of the operation however, any races will at worst |
|
303 # lead to the rename failing and the current operation aborting. |
|
304 |
|
305 def tempname(prefix): |
|
306 for tries in xrange(10): |
|
307 temp = '%s-%08x' % (prefix, random.randint(0, 0xffffffff)) |
|
308 if not os.path.exists(temp): |
|
309 return temp |
|
310 raise IOError, (errno.EEXIST, "No usable temporary filename found") |
|
311 |
|
312 temp = tempname(dst) |
|
313 os.rename(dst, temp) |
|
314 try: |
|
315 os.unlink(temp) |
|
316 except: |
|
317 # Some rude AV-scanners on Windows may cause the unlink to |
|
318 # fail. Not aborting here just leaks the temp file, whereas |
|
319 # aborting at this point may leave serious inconsistencies. |
|
320 # Ideally, we would notify the user here. |
|
321 pass |
|
322 os.rename(src, dst) |
|
323 |
286 try: |
324 try: |
287 # override functions with win32 versions if possible |
325 # override functions with win32 versions if possible |
288 from win32 import * |
326 from win32 import * |
289 except ImportError: |
327 except ImportError: |
290 pass |
328 pass |