1111#include " llbuild/Basic/Stat.h"
1212#include " llvm/ADT/SmallVector.h"
1313#include " llvm/Support/ConvertUTF.h"
14- #include " llvm/Support/Path.h"
1514
1615#if defined(_WIN32)
1716#include " LeanWindows.h"
1817#include < Shlwapi.h>
1918#include < direct.h>
2019#include < io.h>
21- #include < time.h>
2220#else
2321#include < fnmatch.h>
2422#include < unistd.h>
@@ -30,9 +28,7 @@ using namespace llbuild::basic;
3028
3129bool sys::chdir (const char *fileName) {
3230#if defined(_WIN32)
33- llvm::SmallVector<UTF16, 20 > wFileName;
34- llvm::convertUTF8ToUTF16String (fileName, wFileName);
35- return SetCurrentDirectoryW ((LPCWSTR)wFileName.data ());
31+ return SetCurrentDirectoryA (fileName);
3632#else
3733 return ::chdir (fileName) == 0 ;
3834#endif
@@ -46,68 +42,11 @@ int sys::close(int fileHandle) {
4642#endif
4743}
4844
49- #if defined(_WIN32)
50- time_t filetimeToTime_t (FILETIME ft) {
51- long long ltime = ft.dwLowDateTime | ((long long )ft.dwHighDateTime << 32 );
52- return (time_t )((ltime - 116444736000000000 ) / 10000000 );
53- }
54- #endif
55-
5645int sys::lstat (const char *fileName, sys::StatStruct *buf) {
5746#if defined(_WIN32)
58- llvm::SmallVector<UTF16, 20 > wfilename;
59- llvm::convertUTF8ToUTF16String (fileName, wfilename);
60- HANDLE h = CreateFileW (
61- /* lpFileName=*/ (LPCWSTR)wfilename.data (),
62- /* dwDesiredAccess=*/ 0 ,
63- /* dwShareMode=*/ FILE_SHARE_READ,
64- /* lpSecurityAttributes=*/ NULL ,
65- /* dwCreationDisposition=*/ OPEN_EXISTING,
66- /* dwFlagsAndAttributes=*/ FILE_FLAG_OPEN_REPARSE_POINT |
67- FILE_FLAG_BACKUP_SEMANTICS,
68- /* hTemplateFile=*/ NULL );
69- if (h == INVALID_HANDLE_VALUE) {
70- int err = GetLastError ();
71- if (err == ERROR_FILE_NOT_FOUND) {
72- errno = ENOENT;
73- }
74- return -1 ;
75- }
76- BY_HANDLE_FILE_INFORMATION info;
77- GetFileInformationByHandle (h, &info);
78- // Group id is always 0 on Windows
79- buf->st_gid = 0 ;
80- buf->st_atime = filetimeToTime_t (info.ftLastAccessTime );
81- buf->st_ctime = filetimeToTime_t (info.ftCreationTime );
82- buf->st_dev = info.dwVolumeSerialNumber ;
83- // inodes have meaning on FAT/HPFS/NTFS
84- buf->st_ino = 0 ;
85- buf->st_rdev = info.dwVolumeSerialNumber ;
86- buf->st_mode =
87- // On a symlink to a directory, Windows sets both the REPARSE_POINT and
88- // DIRECTORY attributes. Since Windows doesn't provide S_IFLNK and we
89- // want unix style "symlinks to directories are not directories
90- // themselves, we say symlinks are regular files
91- (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
92- ? _S_IFREG
93- : (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? _S_IFDIR
94- : _S_IFREG;
95- buf->st_mode |= (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
96- ? _S_IREAD
97- : _S_IREAD | _S_IWRITE;
98- llvm::StringRef extension =
99- llvm::sys::path::extension (llvm::StringRef (fileName));
100- if (extension == " .exe" || extension == " .cmd" || extension == " .bat" ||
101- extension == " .com" ) {
102- buf->st_mode |= _S_IEXEC;
103- }
104- buf->st_mtime = filetimeToTime_t (info.ftLastWriteTime );
105- buf->st_nlink = info.nNumberOfLinks ;
106- buf->st_size = ((long long )info.nFileSizeHigh << 32 ) | info.nFileSizeLow ;
107- // Uid is always 0 on Windows systems
108- buf->st_uid = 0 ;
109- CloseHandle (h);
110- return 0 ;
47+ // We deliberately ignore lstat on Windows, and delegate
48+ // to stat.
49+ return ::_stat (fileName, buf);
11150#else
11251 return ::lstat (fileName, buf);
11352#endif
@@ -170,25 +109,17 @@ int sys::stat(const char *fileName, StatStruct *buf) {
170109#endif
171110}
172111
173- // Create a symlink named linkPath which contains the string pointsTo
174- int sys::symlink (const char *pointsTo, const char *linkPath) {
112+ int sys::symlink (const char *source, const char *target) {
175113#if defined(_WIN32)
176- llvm::SmallVector<UTF16, 20 > wPointsTo;
177- llvm::convertUTF8ToUTF16String (pointsTo, wPointsTo);
178- llvm::SmallVector<UTF16, 20 > wLinkPath;
179- llvm::convertUTF8ToUTF16String (linkPath, wLinkPath);
180- DWORD attributes = GetFileAttributesW ((LPCWSTR)wPointsTo.data ());
181- DWORD directoryFlag = (attributes != INVALID_FILE_ATTRIBUTES &&
182- attributes & FILE_ATTRIBUTE_DIRECTORY)
183- ? SYMBOLIC_LINK_FLAG_DIRECTORY
184- : 0 ;
185- // Note that CreateSymbolicLinkW takes its arguments in reverse order
186- // compared to symlink/_symlink
187- return !::CreateSymbolicLinkW (
188- (LPCWSTR)wLinkPath.data (), (LPCWSTR)wPointsTo.data (),
189- SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE | directoryFlag);
114+ DWORD attributes = GetFileAttributesA (source);
115+ if (attributes != INVALID_FILE_ATTRIBUTES &&
116+ (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ) {
117+ return ::CreateSymbolicLinkA (source, target, SYMBOLIC_LINK_FLAG_DIRECTORY);
118+ }
119+
120+ return ::CreateSymbolicLinkA (source, target, 0 );
190121#else
191- return ::symlink (pointsTo, linkPath );
122+ return ::symlink (source, target );
192123#endif
193124}
194125
@@ -286,29 +217,23 @@ std::string sys::strerror(int error) {
286217
287218char *sys::strsep (char **stringp, const char *delim) {
288219#if defined(_WIN32)
289- // If *stringp is NULL, the strsep() function returns NULL and does nothing
290- // else.
220+ char *begin, *end = *stringp;
291221 if (*stringp == NULL ) {
292222 return NULL ;
293223 }
294- char *begin = *stringp;
295- char *end = *stringp;
296- do {
297- // Otherwise, this function finds the first token in the string *stringp,
298- // that is delimited by one of the bytes in the string delim.
299- for (int i = 0 ; delim[i] != ' \0 ' ; i++) {
224+ int delimLen = strlen (delim);
225+ bool found = false ;
226+ while (*end) {
227+ for (int i = 0 ; i < delimLen; i++) {
300228 if (*end == delim[i]) {
301- // This token is terminated by overwriting the delimiter with a null
302- // byte ('\0'), and *stringp is updated to point past the token.
303- *end = ' \0 ' ;
304- *stringp = end + 1 ;
305- return begin;
229+ found = true ;
306230 }
307231 }
308- } while (*(++end));
309- // In case no delimiter was found, the token is taken to be the entire string
310- // *stringp, and *stringp is made NULL.
311- *stringp = NULL ;
232+ if (found) {
233+ *stringp = end + 1 ;
234+ }
235+ }
236+ *end = ' \0 ' ;
312237 return begin;
313238#else
314239 return ::strsep (stringp, delim);
@@ -319,20 +244,9 @@ std::string sys::makeTmpDir() {
319244#if defined(_WIN32)
320245 char path[MAX_PATH];
321246 tmpnam_s (path, MAX_PATH);
322- llvm::SmallVector<UTF16, 20 > wPath;
323- llvm::convertUTF8ToUTF16String (path, wPath);
324- CreateDirectoryW ((LPCWSTR)wPath.data (), NULL );
325247 return std::string (path);
326248#else
327249 char tmpDirPathBuf[] = " /tmp/fileXXXXXX" ;
328250 return std::string (mkdtemp (tmpDirPathBuf));
329251#endif
330252}
331-
332- std::string sys::getPathSeparators () {
333- #if defined(_WIN32)
334- return " /\\ " ;
335- #else
336- return " /" ;
337- #endif
338- }
0 commit comments