23 _INVALID_HANDLE_VALUE = _HANDLE(-1).value |
23 _INVALID_HANDLE_VALUE = _HANDLE(-1).value |
24 |
24 |
25 # GetLastError |
25 # GetLastError |
26 _ERROR_SUCCESS = 0 |
26 _ERROR_SUCCESS = 0 |
27 _ERROR_NO_MORE_FILES = 18 |
27 _ERROR_NO_MORE_FILES = 18 |
28 _ERROR_SHARING_VIOLATION = 32 |
|
29 _ERROR_INVALID_PARAMETER = 87 |
28 _ERROR_INVALID_PARAMETER = 87 |
30 _ERROR_INSUFFICIENT_BUFFER = 122 |
29 _ERROR_INSUFFICIENT_BUFFER = 122 |
31 |
30 |
32 # WPARAM is defined as UINT_PTR (unsigned type) |
31 # WPARAM is defined as UINT_PTR (unsigned type) |
33 # LPARAM is defined as LONG_PTR (signed type) |
32 # LPARAM is defined as LONG_PTR (signed type) |
59 _FILE_SHARE_WRITE = 0x00000002 |
58 _FILE_SHARE_WRITE = 0x00000002 |
60 _FILE_SHARE_DELETE = 0x00000004 |
59 _FILE_SHARE_DELETE = 0x00000004 |
61 |
60 |
62 _OPEN_EXISTING = 3 |
61 _OPEN_EXISTING = 3 |
63 |
62 |
64 _FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000 |
|
65 _FILE_FLAG_BACKUP_SEMANTICS = 0x02000000 |
63 _FILE_FLAG_BACKUP_SEMANTICS = 0x02000000 |
66 _FILE_FLAG_DELETE_ON_CLOSE = 0x04000000 |
|
67 |
64 |
68 # SetFileAttributes |
65 # SetFileAttributes |
69 _FILE_ATTRIBUTE_NORMAL = 0x80 |
66 _FILE_ATTRIBUTE_NORMAL = 0x80 |
70 _FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000 |
67 _FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000 |
71 |
68 |
422 return _tochildpid(pi.dwProcessId) |
419 return _tochildpid(pi.dwProcessId) |
423 |
420 |
424 def unlink(f): |
421 def unlink(f): |
425 '''try to implement POSIX' unlink semantics on Windows''' |
422 '''try to implement POSIX' unlink semantics on Windows''' |
426 |
423 |
427 # If we can open f exclusively, no other processes must have open handles |
424 if os.path.isdir(f): |
428 # for it and we can expect its name will be deleted immediately when we |
425 # use EPERM because it is POSIX prescribed value, even though |
429 # close the handle unless we have another in the same process. We also |
426 # unlink(2) on directories returns EISDIR on Linux |
430 # expect we shall simply fail to open f if it is a directory. |
427 raise IOError(errno.EPERM, |
431 fh = _kernel32.CreateFileA(f, 0, 0, None, _OPEN_EXISTING, |
428 "Unlinking directory not permitted: '%s'" % f) |
432 _FILE_FLAG_OPEN_REPARSE_POINT | _FILE_FLAG_DELETE_ON_CLOSE, None) |
|
433 if fh != _INVALID_HANDLE_VALUE: |
|
434 _kernel32.CloseHandle(fh) |
|
435 return |
|
436 error = _kernel32.GetLastError() |
|
437 if error != _ERROR_SHARING_VIOLATION: |
|
438 raise ctypes.WinError(error) |
|
439 |
429 |
440 # POSIX allows to unlink and rename open files. Windows has serious |
430 # POSIX allows to unlink and rename open files. Windows has serious |
441 # problems with doing that: |
431 # problems with doing that: |
442 # - Calling os.unlink (or os.rename) on a file f fails if f or any |
432 # - Calling os.unlink (or os.rename) on a file f fails if f or any |
443 # hardlinked copy of f has been opened with Python's open(). There is no |
433 # hardlinked copy of f has been opened with Python's open(). There is no |