mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
lit: support long paths on Windows
Use ctypes to call into SHFileOperationW with the extended NT path to allow us to remove paths which exceed 261 characters on Windows. This functionality is exercised by swift's test suite. llvm-svn: 357778
This commit is contained in:
parent
e77d808b74
commit
52d35270c6
@ -353,7 +353,7 @@ def executeBuiltinMkdir(cmd, cmd_shenv):
|
||||
lit.util.mkdir_p(dir)
|
||||
else:
|
||||
try:
|
||||
os.mkdir(dir)
|
||||
lit.util.mkdir(dir)
|
||||
except OSError as err:
|
||||
stderr.write("Error: 'mkdir' command failed, %s\n" % str(err))
|
||||
exitCode = 1
|
||||
@ -613,7 +613,49 @@ def executeBuiltinRm(cmd, cmd_shenv):
|
||||
if not recursive:
|
||||
stderr.write("Error: %s is a directory\n" % path)
|
||||
exitCode = 1
|
||||
shutil.rmtree(path, onerror = on_rm_error if force else None)
|
||||
if platform.system() == 'Windows':
|
||||
# NOTE: use ctypes to access `SHFileOperationsW` on Windows to
|
||||
# use the NT style path to get access to long file paths which
|
||||
# cannot be removed otherwise.
|
||||
from ctypes.wintypes import BOOL, HWND, LPCWSTR, POINTER, UINT, WORD
|
||||
from ctypes import c_void_p, byref
|
||||
from ctypes import Structure
|
||||
from ctypes import windll, WinError
|
||||
|
||||
class SHFILEOPSTRUCTW(Structure):
|
||||
_fields_ = [
|
||||
('hWnd', HWND),
|
||||
('wFunc', UINT),
|
||||
('pFrom', LPCWSTR),
|
||||
('pTo', LPCWSTR),
|
||||
('fFlags', WORD),
|
||||
('fAnyOperationsAborted', BOOL),
|
||||
('hNameMappings', c_void_p),
|
||||
('lpszProgressTitle', LPCWSTR),
|
||||
]
|
||||
|
||||
FO_MOVE, FO_COPY, FO_DELETE, FO_RENAME = xrange(1, 5)
|
||||
|
||||
FOF_SILENT = 4
|
||||
FOF_NOCONFIRMATION = 16
|
||||
FOF_NOCONFIRMMKDIR = 512
|
||||
FOF_NOERRORUI = 1024
|
||||
|
||||
FOF_NO_UI = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR
|
||||
|
||||
SHFileOperationW = windll.shell32.SHFileOperationW
|
||||
SHFileOperationW.argtypes = [POINTER(SHFILEOPSTRUCTW)]
|
||||
|
||||
path = os.path.abspath(path)
|
||||
|
||||
operation = SHFILEOPSTRUCTW(wFunc=UINT(FO_DELETE),
|
||||
pFrom=LPCWSTR(unicode(path + '\0')),
|
||||
fFlags=FOF_NO_UI)
|
||||
result = SHFileOperationW(byref(operation))
|
||||
if result:
|
||||
raise WinError(result)
|
||||
else:
|
||||
shutil.rmtree(path, onerror = on_rm_error if force else None)
|
||||
else:
|
||||
if force and not os.access(path, os.W_OK):
|
||||
os.chmod(path,
|
||||
|
@ -142,6 +142,25 @@ def detectCPUs():
|
||||
return 1 # Default
|
||||
|
||||
|
||||
def mkdir(path):
|
||||
try:
|
||||
if platform.system() == 'Windows':
|
||||
from ctypes import windll
|
||||
from ctypes import GetLastError, WinError
|
||||
|
||||
path = os.path.abspath(path)
|
||||
NTPath = unicode(r'\\?\%s' % path)
|
||||
if not windll.kernel32.CreateDirectoryW(NTPath, None):
|
||||
raise WinError(GetLastError())
|
||||
else:
|
||||
os.mkdir(path)
|
||||
except OSError:
|
||||
e = sys.exc_info()[1]
|
||||
# ignore EEXIST, which may occur during a race condition
|
||||
if e.errno != errno.EEXIST:
|
||||
raise
|
||||
|
||||
|
||||
def mkdir_p(path):
|
||||
"""mkdir_p(path) - Make the "path" directory, if it does not exist; this
|
||||
will also make directories for any missing parent directories."""
|
||||
@ -152,13 +171,7 @@ def mkdir_p(path):
|
||||
if parent != path:
|
||||
mkdir_p(parent)
|
||||
|
||||
try:
|
||||
os.mkdir(path)
|
||||
except OSError:
|
||||
e = sys.exc_info()[1]
|
||||
# Ignore EEXIST, which may occur during a race condition.
|
||||
if e.errno != errno.EEXIST:
|
||||
raise
|
||||
mkdir(path)
|
||||
|
||||
|
||||
def listdir_files(dirname, suffixes=None, exclude_filenames=None):
|
||||
|
Loading…
Reference in New Issue
Block a user