Skip to content

Commit cbac2d9

Browse files
authored
Merge pull request #1007 from swiftlang/revert-1004-windows_long_file_fix
Revert "use Win32 file APIs and widePath for file ops to support long filenames"
2 parents fa78e46 + a344d3c commit cbac2d9

File tree

2 files changed

+41
-146
lines changed

2 files changed

+41
-146
lines changed

lib/Basic/PlatformUtility.cpp

Lines changed: 34 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,9 @@ using namespace llbuild::basic;
3838

3939
bool sys::chdir(const char *fileName) {
4040
#if defined(_WIN32)
41-
llvm::SmallVector<wchar_t, MAX_PATH> wFileName;
42-
if (llvm::sys::path::widenPath(fileName, wFileName))
43-
return false;
44-
return SetCurrentDirectoryW(wFileName.data());
41+
llvm::SmallVector<llvm::UTF16, 20> wFileName;
42+
llvm::convertUTF8ToUTF16String(fileName, wFileName);
43+
return SetCurrentDirectoryW((LPCWSTR)wFileName.data());
4544
#else
4645
return ::chdir(fileName) == 0;
4746
#endif
@@ -64,13 +63,10 @@ time_t filetimeToTime_t(FILETIME ft) {
6463

6564
int sys::lstat(const char *fileName, sys::StatStruct *buf) {
6665
#if defined(_WIN32)
67-
llvm::SmallVector<wchar_t, MAX_PATH> wfilename;
68-
if (llvm::sys::path::widenPath(fileName, wfilename)) {
69-
errno = EINVAL;
70-
return -1;
71-
}
66+
llvm::SmallVector<llvm::UTF16, 20> wfilename;
67+
llvm::convertUTF8ToUTF16String(fileName, wfilename);
7268
HANDLE h = CreateFileW(
73-
/*lpFileName=*/wfilename.data(),
69+
/*lpFileName=*/(LPCWSTR)wfilename.data(),
7470
/*dwDesiredAccess=*/0,
7571
/*dwShareMode=*/FILE_SHARE_READ,
7672
/*lpSecurityAttributes=*/NULL,
@@ -127,10 +123,7 @@ int sys::lstat(const char *fileName, sys::StatStruct *buf) {
127123

128124
bool sys::mkdir(const char* fileName) {
129125
#if defined(_WIN32)
130-
llvm::SmallVector<wchar_t, MAX_PATH> wfilename;
131-
if (llvm::sys::path::widenPath(fileName, wfilename))
132-
return false;
133-
return CreateDirectoryW(wfilename.data(), NULL) != 0;
126+
return _mkdir(fileName) == 0;
134127
#else
135128
return ::mkdir(fileName, S_IRWXU | S_IRWXG | S_IRWXO) == 0;
136129
#endif
@@ -171,72 +164,15 @@ int sys::read(int fileHandle, void *destinationBuffer,
171164

172165
int sys::rmdir(const char *path) {
173166
#if defined(_WIN32)
174-
llvm::SmallVector<wchar_t, MAX_PATH> wpath;
175-
if (llvm::sys::path::widenPath(path, wpath)) {
176-
errno = EINVAL;
177-
return -1;
178-
}
179-
if (RemoveDirectoryW(wpath.data())) {
180-
return 0;
181-
}
182-
int err = GetLastError();
183-
if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) {
184-
errno = ENOENT;
185-
} else if (err == ERROR_ACCESS_DENIED) {
186-
errno = EACCES;
187-
} else if (err == ERROR_DIR_NOT_EMPTY) {
188-
errno = ENOTEMPTY;
189-
} else {
190-
errno = EINVAL;
191-
}
192-
return -1;
167+
return ::_rmdir(path);
193168
#else
194169
return ::rmdir(path);
195170
#endif
196171
}
197172

198173
int sys::stat(const char *fileName, StatStruct *buf) {
199174
#if defined(_WIN32)
200-
llvm::SmallVector<wchar_t, MAX_PATH> wfilename;
201-
if (llvm::sys::path::widenPath(fileName, wfilename)) {
202-
errno = EINVAL;
203-
return -1;
204-
}
205-
206-
WIN32_FILE_ATTRIBUTE_DATA fileData;
207-
if (!GetFileAttributesExW(wfilename.data(), GetFileExInfoStandard, &fileData)) {
208-
int err = GetLastError();
209-
if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) {
210-
errno = ENOENT;
211-
} else if (err == ERROR_ACCESS_DENIED) {
212-
errno = EACCES;
213-
} else {
214-
errno = EINVAL;
215-
}
216-
return -1;
217-
}
218-
219-
// Fill the stat structure
220-
buf->st_gid = 0;
221-
buf->st_atime = filetimeToTime_t(fileData.ftLastAccessTime);
222-
buf->st_ctime = filetimeToTime_t(fileData.ftCreationTime);
223-
buf->st_dev = 0;
224-
buf->st_ino = 0;
225-
buf->st_rdev = 0;
226-
buf->st_mode = (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? _S_IFDIR : _S_IFREG;
227-
buf->st_mode |= (fileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? _S_IREAD : _S_IREAD | _S_IWRITE;
228-
229-
llvm::StringRef extension = llvm::sys::path::extension(llvm::StringRef(fileName));
230-
if (extension == ".exe" || extension == ".cmd" || extension == ".bat" || extension == ".com") {
231-
buf->st_mode |= _S_IEXEC;
232-
}
233-
234-
buf->st_mtime = filetimeToTime_t(fileData.ftLastWriteTime);
235-
buf->st_nlink = 1;
236-
buf->st_size = ((long long)fileData.nFileSizeHigh << 32) | fileData.nFileSizeLow;
237-
buf->st_uid = 0;
238-
239-
return 0;
175+
return ::_stat(fileName, buf);
240176
#else
241177
return ::stat(fileName, buf);
242178
#endif
@@ -245,21 +181,19 @@ int sys::stat(const char *fileName, StatStruct *buf) {
245181
// Create a symlink named linkPath which contains the string pointsTo
246182
int sys::symlink(const char *pointsTo, const char *linkPath) {
247183
#if defined(_WIN32)
248-
llvm::SmallVector<wchar_t, MAX_PATH> wPointsTo;
249-
if (llvm::sys::path::widenPath(pointsTo, wPointsTo))
250-
return -1;
251-
llvm::SmallVector<wchar_t, MAX_PATH> wLinkPath;
252-
if (llvm::sys::path::widenPath(linkPath, wLinkPath))
253-
return -1;
254-
DWORD attributes = GetFileAttributesW(wPointsTo.data());
184+
llvm::SmallVector<llvm::UTF16, 20> wPointsTo;
185+
llvm::convertUTF8ToUTF16String(pointsTo, wPointsTo);
186+
llvm::SmallVector<llvm::UTF16, 20> wLinkPath;
187+
llvm::convertUTF8ToUTF16String(linkPath, wLinkPath);
188+
DWORD attributes = GetFileAttributesW((LPCWSTR)wPointsTo.data());
255189
DWORD directoryFlag = (attributes != INVALID_FILE_ATTRIBUTES &&
256190
attributes & FILE_ATTRIBUTE_DIRECTORY)
257191
? SYMBOLIC_LINK_FLAG_DIRECTORY
258192
: 0;
259193
// Note that CreateSymbolicLinkW takes its arguments in reverse order
260194
// compared to symlink/_symlink
261195
return !::CreateSymbolicLinkW(
262-
wLinkPath.data(), wPointsTo.data(),
196+
(LPCWSTR)wLinkPath.data(), (LPCWSTR)wPointsTo.data(),
263197
SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE | directoryFlag);
264198
#else
265199
return ::symlink(pointsTo, linkPath);
@@ -268,23 +202,7 @@ int sys::symlink(const char *pointsTo, const char *linkPath) {
268202

269203
int sys::unlink(const char *fileName) {
270204
#if defined(_WIN32)
271-
llvm::SmallVector<wchar_t, MAX_PATH> wfilename;
272-
if (llvm::sys::path::widenPath(fileName, wfilename)) {
273-
errno = EINVAL;
274-
return -1;
275-
}
276-
if (DeleteFileW(wfilename.data())) {
277-
return 0;
278-
}
279-
int err = GetLastError();
280-
if (err == ERROR_FILE_NOT_FOUND) {
281-
errno = ENOENT;
282-
} else if (err == ERROR_ACCESS_DENIED) {
283-
errno = EACCES;
284-
} else {
285-
errno = EINVAL;
286-
}
287-
return -1;
205+
return ::_unlink(fileName);
288206
#else
289207
return ::unlink(fileName);
290208
#endif
@@ -345,15 +263,14 @@ int sys::raiseOpenFileLimit(llbuild_rlim_t limit) {
345263
sys::MATCH_RESULT sys::filenameMatch(const std::string& pattern,
346264
const std::string& filename) {
347265
#if defined(_WIN32)
348-
llvm::SmallVector<wchar_t, MAX_PATH> wpattern;
349-
llvm::SmallVector<wchar_t, MAX_PATH> wfilename;
266+
llvm::SmallVector<llvm::UTF16, 20> wpattern;
267+
llvm::SmallVector<llvm::UTF16, 20> wfilename;
350268

351-
if (llvm::sys::path::widenPath(pattern, wpattern) ||
352-
llvm::sys::path::widenPath(filename, wfilename))
353-
return sys::MATCH_ERROR;
269+
llvm::convertUTF8ToUTF16String(pattern, wpattern);
270+
llvm::convertUTF8ToUTF16String(filename, wfilename);
354271

355272
bool result =
356-
PathMatchSpecW(wfilename.data(), wpattern.data());
273+
PathMatchSpecW((LPCWSTR)wfilename.data(), (LPCWSTR)wpattern.data());
357274
return result ? sys::MATCH : sys::NO_MATCH;
358275
#else
359276
int result = fnmatch(pattern.c_str(), filename.c_str(), 0);
@@ -425,17 +342,9 @@ std::string sys::makeTmpDir() {
425342
#if defined(_WIN32)
426343
char path[MAX_PATH];
427344
tmpnam_s(path, MAX_PATH);
428-
llvm::SmallVector<wchar_t, MAX_PATH> wPath;
429-
if (llvm::sys::path::widenPath(path, wPath))
430-
return std::string();
431-
if (!CreateDirectoryW(wPath.data(), NULL)) {
432-
DWORD error = GetLastError();
433-
if (error != ERROR_ALREADY_EXISTS) {
434-
fprintf(stderr, "Failed to create temporary directory '%s': error code %lu\n",
435-
path, (unsigned long)error);
436-
return std::string();
437-
}
438-
}
345+
llvm::SmallVector<llvm::UTF16, 20> wPath;
346+
llvm::convertUTF8ToUTF16String(path, wPath);
347+
CreateDirectoryW((LPCWSTR)wPath.data(), NULL);
439348
return std::string(path);
440349
#else
441350
if (const char *tmpDir = std::getenv("TMPDIR")) {
@@ -462,10 +371,15 @@ std::string sys::getPathSeparators() {
462371

463372
sys::ModuleTraits<>::Handle sys::OpenLibrary(const char *path) {
464373
#if defined(_WIN32)
465-
llvm::SmallVector<wchar_t, MAX_PATH> wPath;
466-
if (llvm::sys::path::widenPath(path, wPath))
467-
return nullptr;
468-
return LoadLibraryW(wPath.data());
374+
int cchLength =
375+
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, strlen(path),
376+
nullptr, 0);
377+
std::u16string buffer(cchLength + 1, 0);
378+
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, strlen(path),
379+
const_cast<LPWSTR>(reinterpret_cast<LPCWSTR>(buffer.data())),
380+
buffer.size());
381+
382+
return LoadLibraryW(reinterpret_cast<LPCWSTR>(buffer.data()));
469383
#else
470384
return dlopen(path, RTLD_LAZY);
471385
#endif
@@ -487,3 +401,4 @@ void sys::CloseLibrary(sys::ModuleTraits<>::Handle handle) {
487401
dlclose(handle);
488402
#endif
489403
}
404+

src/llbuild3/LocalExecutor.cpp

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -246,47 +246,27 @@ std::string formatWindowsCommandString(std::vector<std::string> args) {
246246

247247
std::error_code checkExecutable(const std::filesystem::path& path) {
248248

249-
#if defined(_WIN32)
250-
llvm::SmallVector<wchar_t, MAX_PATH> wpath;
251-
if (llvm::sys::path::widenPath(path.c_str(), wpath)) {
252-
return std::make_error_code(std::errc::invalid_argument);
253-
}
254-
255-
DWORD attributes = GetFileAttributesW(wpath.data());
256-
if (attributes == INVALID_FILE_ATTRIBUTES) {
257-
DWORD err = GetLastError();
258-
if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) {
259-
return std::make_error_code(std::errc::no_such_file_or_directory);
260-
} else if (err == ERROR_ACCESS_DENIED) {
261-
return std::make_error_code(std::errc::permission_denied);
262-
} else {
263-
return std::error_code(err, std::system_category());
264-
}
265-
}
266-
#else
267249
if (::access(path.c_str(), R_OK | X_OK) == -1) {
268250
return std::error_code(errno, std::generic_category());
269251
}
270-
#endif
271252

272253
// Don't say that directories are executable.
273254
#if defined(_WIN32)
274-
WIN32_FILE_ATTRIBUTE_DATA fileData;
275-
if (!GetFileAttributesExW(wpath.data(), GetFileExInfoStandard, &fileData)) {
276-
return std::make_error_code(std::errc::permission_denied);
277-
}
278-
279-
if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
280-
return std::make_error_code(std::errc::permission_denied);
255+
struct ::_stat buf;
281256
#else
282257
struct ::stat buf;
258+
#endif
259+
260+
#if defined(_WIN32)
261+
if (0 != ::_stat(path.c_str(), &buf)) {
262+
#else
283263
if (0 != ::stat(path.c_str(), &buf)) {
264+
#endif
284265
return std::make_error_code(std::errc::permission_denied);
285266
}
286267

287268
if (!S_ISREG(buf.st_mode))
288269
return std::make_error_code(std::errc::permission_denied);
289-
#endif
290270

291271
return std::error_code();
292272
}

0 commit comments

Comments
 (0)