@@ -38,9 +38,10 @@ using namespace llbuild::basic;
38
38
39
39
bool sys::chdir (const char *fileName) {
40
40
#if defined(_WIN32)
41
- llvm::SmallVector<llvm::UTF16, 20 > wFileName;
42
- llvm::convertUTF8ToUTF16String (fileName, wFileName);
43
- return SetCurrentDirectoryW ((LPCWSTR)wFileName.data ());
41
+ llvm::SmallVector<wchar_t , MAX_PATH> wFileName;
42
+ if (llvm::sys::path::widenPath (fileName, wFileName))
43
+ return false ;
44
+ return SetCurrentDirectoryW (wFileName.data ());
44
45
#else
45
46
return ::chdir (fileName) == 0 ;
46
47
#endif
@@ -63,10 +64,13 @@ time_t filetimeToTime_t(FILETIME ft) {
63
64
64
65
int sys::lstat (const char *fileName, sys::StatStruct *buf) {
65
66
#if defined(_WIN32)
66
- llvm::SmallVector<llvm::UTF16, 20 > wfilename;
67
- llvm::convertUTF8ToUTF16String (fileName, wfilename);
67
+ llvm::SmallVector<wchar_t , MAX_PATH> wfilename;
68
+ if (llvm::sys::path::widenPath (fileName, wfilename)) {
69
+ errno = EINVAL;
70
+ return -1 ;
71
+ }
68
72
HANDLE h = CreateFileW (
69
- /* lpFileName=*/ (LPCWSTR) wfilename.data (),
73
+ /* lpFileName=*/ wfilename.data (),
70
74
/* dwDesiredAccess=*/ 0 ,
71
75
/* dwShareMode=*/ FILE_SHARE_READ,
72
76
/* lpSecurityAttributes=*/ NULL ,
@@ -123,7 +127,10 @@ int sys::lstat(const char *fileName, sys::StatStruct *buf) {
123
127
124
128
bool sys::mkdir (const char * fileName) {
125
129
#if defined(_WIN32)
126
- return _mkdir (fileName) == 0 ;
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 ;
127
134
#else
128
135
return ::mkdir (fileName, S_IRWXU | S_IRWXG | S_IRWXO) == 0 ;
129
136
#endif
@@ -164,15 +171,72 @@ int sys::read(int fileHandle, void *destinationBuffer,
164
171
165
172
int sys::rmdir (const char *path) {
166
173
#if defined(_WIN32)
167
- return ::_rmdir (path);
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 ;
168
193
#else
169
194
return ::rmdir (path);
170
195
#endif
171
196
}
172
197
173
198
int sys::stat (const char *fileName, StatStruct *buf) {
174
199
#if defined(_WIN32)
175
- return ::_stat (fileName, buf);
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 ;
176
240
#else
177
241
return ::stat (fileName, buf);
178
242
#endif
@@ -181,19 +245,21 @@ int sys::stat(const char *fileName, StatStruct *buf) {
181
245
// Create a symlink named linkPath which contains the string pointsTo
182
246
int sys::symlink (const char *pointsTo, const char *linkPath) {
183
247
#if defined(_WIN32)
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 ());
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 ());
189
255
DWORD directoryFlag = (attributes != INVALID_FILE_ATTRIBUTES &&
190
256
attributes & FILE_ATTRIBUTE_DIRECTORY)
191
257
? SYMBOLIC_LINK_FLAG_DIRECTORY
192
258
: 0 ;
193
259
// Note that CreateSymbolicLinkW takes its arguments in reverse order
194
260
// compared to symlink/_symlink
195
261
return !::CreateSymbolicLinkW (
196
- (LPCWSTR) wLinkPath.data (), (LPCWSTR) wPointsTo.data (),
262
+ wLinkPath.data (), wPointsTo.data (),
197
263
SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE | directoryFlag);
198
264
#else
199
265
return ::symlink (pointsTo, linkPath);
@@ -202,7 +268,23 @@ int sys::symlink(const char *pointsTo, const char *linkPath) {
202
268
203
269
int sys::unlink (const char *fileName) {
204
270
#if defined(_WIN32)
205
- return ::_unlink (fileName);
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 ;
206
288
#else
207
289
return ::unlink (fileName);
208
290
#endif
@@ -263,14 +345,15 @@ int sys::raiseOpenFileLimit(llbuild_rlim_t limit) {
263
345
sys::MATCH_RESULT sys::filenameMatch (const std::string& pattern,
264
346
const std::string& filename) {
265
347
#if defined(_WIN32)
266
- llvm::SmallVector<llvm::UTF16, 20 > wpattern;
267
- llvm::SmallVector<llvm::UTF16, 20 > wfilename;
348
+ llvm::SmallVector<wchar_t , MAX_PATH > wpattern;
349
+ llvm::SmallVector<wchar_t , MAX_PATH > wfilename;
268
350
269
- llvm::convertUTF8ToUTF16String (pattern, wpattern);
270
- llvm::convertUTF8ToUTF16String (filename, wfilename);
351
+ if (llvm::sys::path::widenPath (pattern, wpattern) ||
352
+ llvm::sys::path::widenPath (filename, wfilename))
353
+ return sys::MATCH_ERROR;
271
354
272
355
bool result =
273
- PathMatchSpecW ((LPCWSTR) wfilename.data (), (LPCWSTR) wpattern.data ());
356
+ PathMatchSpecW (wfilename.data (), wpattern.data ());
274
357
return result ? sys::MATCH : sys::NO_MATCH;
275
358
#else
276
359
int result = fnmatch (pattern.c_str (), filename.c_str (), 0 );
@@ -342,9 +425,10 @@ std::string sys::makeTmpDir() {
342
425
#if defined(_WIN32)
343
426
char path[MAX_PATH];
344
427
tmpnam_s (path, MAX_PATH);
345
- llvm::SmallVector<llvm::UTF16, 20 > wPath;
346
- llvm::convertUTF8ToUTF16String (path, wPath);
347
- CreateDirectoryW ((LPCWSTR)wPath.data (), NULL );
428
+ llvm::SmallVector<wchar_t , MAX_PATH> wPath;
429
+ if (llvm::sys::path::widenPath (path, wPath))
430
+ return std::string ();
431
+ CreateDirectoryW (wPath.data (), NULL );
348
432
return std::string (path);
349
433
#else
350
434
if (const char *tmpDir = std::getenv (" TMPDIR" )) {
@@ -371,15 +455,10 @@ std::string sys::getPathSeparators() {
371
455
372
456
sys::ModuleTraits<>::Handle sys::OpenLibrary (const char *path) {
373
457
#if defined(_WIN32)
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 ()));
458
+ llvm::SmallVector<wchar_t , MAX_PATH> wPath;
459
+ if (llvm::sys::path::widenPath (path, wPath))
460
+ return nullptr ;
461
+ return LoadLibraryW (wPath.data ());
383
462
#else
384
463
return dlopen (path, RTLD_LAZY);
385
464
#endif
@@ -401,4 +480,3 @@ void sys::CloseLibrary(sys::ModuleTraits<>::Handle handle) {
401
480
dlclose (handle);
402
481
#endif
403
482
}
404
-
0 commit comments