diff options
Diffstat (limited to 'lib/Support/Windows')
-rw-r--r-- | lib/Support/Windows/PathV2.inc | 128 | ||||
-rw-r--r-- | lib/Support/Windows/Program.inc | 36 | ||||
-rw-r--r-- | lib/Support/Windows/Signals.inc | 2 | ||||
-rw-r--r-- | lib/Support/Windows/Windows.h | 106 |
4 files changed, 142 insertions, 130 deletions
diff --git a/lib/Support/Windows/PathV2.inc b/lib/Support/Windows/PathV2.inc index bc597b2..7ca33c0 100644 --- a/lib/Support/Windows/PathV2.inc +++ b/lib/Support/Windows/PathV2.inc @@ -17,7 +17,6 @@ //===----------------------------------------------------------------------===// #include "Windows.h" -#include <wincrypt.h> #include <fcntl.h> #include <io.h> #include <sys/stat.h> @@ -112,14 +111,6 @@ namespace { return success; } - // Forwarder for ScopedHandle. - BOOL WINAPI CryptReleaseContext(HCRYPTPROV Provider) { - return ::CryptReleaseContext(Provider, 0); - } - - typedef ScopedHandle<HCRYPTPROV, uintptr_t(-1), - BOOL (WINAPI*)(HCRYPTPROV), CryptReleaseContext> - ScopedCryptContext; bool is_separator(const wchar_t value) { switch (value) { case L'\\': @@ -359,68 +350,22 @@ error_code exists(const Twine &path, bool &result) { return success; } -error_code equivalent(const Twine &A, const Twine &B, bool &result) { - // Get arguments. - SmallString<128> a_storage; - SmallString<128> b_storage; - StringRef a = A.toStringRef(a_storage); - StringRef b = B.toStringRef(b_storage); - - // Convert to utf-16. - SmallVector<wchar_t, 128> wide_a; - SmallVector<wchar_t, 128> wide_b; - if (error_code ec = UTF8ToUTF16(a, wide_a)) return ec; - if (error_code ec = UTF8ToUTF16(b, wide_b)) return ec; - - AutoHandle HandleB( - ::CreateFileW(wide_b.begin(), - 0, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - 0)); - - AutoHandle HandleA( - ::CreateFileW(wide_a.begin(), - 0, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - 0)); - - // If both handles are invalid, it's an error. - if (HandleA == INVALID_HANDLE_VALUE && - HandleB == INVALID_HANDLE_VALUE) - return windows_error(::GetLastError()); - - // If only one is invalid, it's false. - if (HandleA == INVALID_HANDLE_VALUE && - HandleB == INVALID_HANDLE_VALUE) { - result = false; - return success; - } - - // Get file information. - BY_HANDLE_FILE_INFORMATION InfoA, InfoB; - if (!::GetFileInformationByHandle(HandleA, &InfoA)) - return windows_error(::GetLastError()); - if (!::GetFileInformationByHandle(HandleB, &InfoB)) - return windows_error(::GetLastError()); - - // See if it's all the same. - result = - InfoA.dwVolumeSerialNumber == InfoB.dwVolumeSerialNumber && - InfoA.nFileIndexHigh == InfoB.nFileIndexHigh && - InfoA.nFileIndexLow == InfoB.nFileIndexLow && - InfoA.nFileSizeHigh == InfoB.nFileSizeHigh && - InfoA.nFileSizeLow == InfoB.nFileSizeLow && - InfoA.ftLastWriteTime.dwLowDateTime == - InfoB.ftLastWriteTime.dwLowDateTime && - InfoA.ftLastWriteTime.dwHighDateTime == - InfoB.ftLastWriteTime.dwHighDateTime; +bool equivalent(file_status A, file_status B) { + assert(status_known(A) && status_known(B)); + return A.FileIndexHigh == B.FileIndexHigh && + A.FileIndexLow == B.FileIndexLow && + A.FileSizeHigh == B.FileSizeHigh && + A.FileSizeLow == B.FileSizeLow && + A.LastWriteTimeHigh == B.LastWriteTimeHigh && + A.LastWriteTimeLow == B.LastWriteTimeLow && + A.VolumeSerialNumber == B.VolumeSerialNumber; +} +error_code equivalent(const Twine &A, const Twine &B, bool &result) { + file_status fsA, fsB; + if (error_code ec = status(A, fsA)) return ec; + if (error_code ec = status(B, fsB)) return ec; + result = equivalent(fsA, fsB); return success; } @@ -478,8 +423,7 @@ error_code status(const Twine &path, file_status &result) { return success; } - if (error_code ec = UTF8ToUTF16(path8, - path_utf16)) + if (error_code ec = UTF8ToUTF16(path8, path_utf16)) return ec; DWORD attr = ::GetFileAttributesW(path_utf16.begin()); @@ -488,7 +432,7 @@ error_code status(const Twine &path, file_status &result) { // Handle reparse points. if (attr & FILE_ATTRIBUTE_REPARSE_POINT) { - AutoHandle h( + ScopedFileHandle h( ::CreateFileW(path_utf16.begin(), 0, // Attributes only. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, @@ -496,14 +440,35 @@ error_code status(const Twine &path, file_status &result) { OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); - if (h == INVALID_HANDLE_VALUE) + if (!h) goto handle_status_error; } if (attr & FILE_ATTRIBUTE_DIRECTORY) result = file_status(file_type::directory_file); - else + else { result = file_status(file_type::regular_file); + ScopedFileHandle h( + ::CreateFileW(path_utf16.begin(), + 0, // Attributes only. + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + 0)); + if (!h) + goto handle_status_error; + BY_HANDLE_FILE_INFORMATION Info; + if (!::GetFileInformationByHandle(h, &Info)) + goto handle_status_error; + result.FileIndexHigh = Info.nFileIndexHigh; + result.FileIndexLow = Info.nFileIndexLow; + result.FileSizeHigh = Info.nFileSizeHigh; + result.FileSizeLow = Info.nFileSizeLow; + result.LastWriteTimeHigh = Info.ftLastWriteTime.dwHighDateTime; + result.LastWriteTimeLow = Info.ftLastWriteTime.dwLowDateTime; + result.VolumeSerialNumber = Info.dwVolumeSerialNumber; + } return success; @@ -535,7 +500,7 @@ error_code unique_file(const Twine &model, int &result_fd, if (makeAbsolute) { // Make model absolute by prepending a temp directory if it's not already. bool absolute = path::is_absolute(m); - + if (!absolute) { SmallVector<wchar_t, 64> temp_dir; if (error_code ec = TempDir(temp_dir)) return ec; @@ -691,7 +656,8 @@ error_code get_magic(const Twine &path, uint32_t len, return success; } -error_code directory_iterator_construct(directory_iterator &it, StringRef path){ +error_code detail::directory_iterator_construct(detail::DirIterState &it, + StringRef path){ SmallVector<wchar_t, 128> path_utf16; if (error_code ec = UTF8ToUTF16(path, @@ -722,7 +688,7 @@ error_code directory_iterator_construct(directory_iterator &it, StringRef path){ error_code ec = windows_error(::GetLastError()); // Check for end. if (ec == windows_error::no_more_files) - return directory_iterator_destruct(it); + return detail::directory_iterator_destruct(it); return ec; } else FilenameLen = ::wcslen(FirstFind.cFileName); @@ -742,7 +708,7 @@ error_code directory_iterator_construct(directory_iterator &it, StringRef path){ return success; } -error_code directory_iterator_destruct(directory_iterator& it) { +error_code detail::directory_iterator_destruct(detail::DirIterState &it) { if (it.IterationHandle != 0) // Closes the handle if it's valid. ScopedFindHandle close(HANDLE(it.IterationHandle)); @@ -751,13 +717,13 @@ error_code directory_iterator_destruct(directory_iterator& it) { return success; } -error_code directory_iterator_increment(directory_iterator& it) { +error_code detail::directory_iterator_increment(detail::DirIterState &it) { WIN32_FIND_DATAW FindData; if (!::FindNextFileW(HANDLE(it.IterationHandle), &FindData)) { error_code ec = windows_error(::GetLastError()); // Check for end. if (ec == windows_error::no_more_files) - return directory_iterator_destruct(it); + return detail::directory_iterator_destruct(it); return ec; } diff --git a/lib/Support/Windows/Program.inc b/lib/Support/Windows/Program.inc index 7e38168..80ccaa6 100644 --- a/lib/Support/Windows/Program.inc +++ b/lib/Support/Windows/Program.inc @@ -299,14 +299,14 @@ Program::Execute(const Path& path, Data_ = wpi; // Make sure these get closed no matter what. - AutoHandle hThread(pi.hThread); + ScopedCommonHandle hThread(pi.hThread); // Assign the process to a job if a memory limit is defined. - AutoHandle hJob(0); + ScopedJobHandle hJob; if (memoryLimit != 0) { hJob = CreateJobObject(0, 0); bool success = false; - if (hJob != 0) { + if (hJob) { JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli; memset(&jeli, 0, sizeof(jeli)); jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY; @@ -367,7 +367,17 @@ Program::Wait(const Path &path, return -2; } - return status & 0377; + if (!status) + return 0; + + // Pass 10(Warning) and 11(Error) to the callee as negative value. + if ((status & 0xBFFF0000U) == 0x80000000U) + return (int)status; + + if (status & 0xFF) + return status & 0x7FFFFFFF; + + return 1; } bool @@ -387,19 +397,25 @@ Program::Kill(std::string* ErrMsg) { return false; } -bool Program::ChangeStdinToBinary(){ +error_code Program::ChangeStdinToBinary(){ int result = _setmode( _fileno(stdin), _O_BINARY ); - return result == -1; + if (result == -1) + return error_code(errno, generic_category()); + return make_error_code(errc::success); } -bool Program::ChangeStdoutToBinary(){ +error_code Program::ChangeStdoutToBinary(){ int result = _setmode( _fileno(stdout), _O_BINARY ); - return result == -1; + if (result == -1) + return error_code(errno, generic_category()); + return make_error_code(errc::success); } -bool Program::ChangeStderrToBinary(){ +error_code Program::ChangeStderrToBinary(){ int result = _setmode( _fileno(stderr), _O_BINARY ); - return result == -1; + if (result == -1) + return error_code(errno, generic_category()); + return make_error_code(errc::success); } } diff --git a/lib/Support/Windows/Signals.inc b/lib/Support/Windows/Signals.inc index 0d4b8a2..3a7e90b 100644 --- a/lib/Support/Windows/Signals.inc +++ b/lib/Support/Windows/Signals.inc @@ -446,7 +446,7 @@ static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) { } if (ExitOnUnhandledExceptions) - _exit(-3); + _exit(ep->ExceptionRecord->ExceptionCode); // Allow dialog box to pop up allowing choice to start debugger. if (OldFilter) diff --git a/lib/Support/Windows/Windows.h b/lib/Support/Windows/Windows.h index 67b6f01..5c1da0d 100644 --- a/lib/Support/Windows/Windows.h +++ b/lib/Support/Windows/Windows.h @@ -26,6 +26,7 @@ #include "llvm/Config/config.h" // Get build system configuration settings #include <windows.h> +#include <wincrypt.h> #include <shlobj.h> #include <cassert> #include <string> @@ -41,70 +42,99 @@ inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) { return true; } -class AutoHandle { - HANDLE handle; +template <typename HandleTraits> +class ScopedHandle { + typedef typename HandleTraits::handle_type handle_type; + handle_type Handle; + ScopedHandle(const ScopedHandle &other); // = delete; + void operator=(const ScopedHandle &other); // = delete; public: - AutoHandle(HANDLE h) : handle(h) {} + ScopedHandle() + : Handle(HandleTraits::GetInvalid()) {} + + explicit ScopedHandle(handle_type h) + : Handle(h) {} - ~AutoHandle() { - if (handle) - CloseHandle(handle); + ~ScopedHandle() { + if (HandleTraits::IsValid(Handle)) + HandleTraits::Close(Handle); } - operator HANDLE() { - return handle; + handle_type take() { + handle_type t = Handle; + Handle = HandleTraits::GetInvalid(); + return t; } - AutoHandle &operator=(HANDLE h) { - handle = h; + ScopedHandle &operator=(handle_type h) { + if (HandleTraits::IsValid(Handle)) + HandleTraits::Close(Handle); + Handle = h; return *this; } + + // True if Handle is valid. + operator bool() const { + return HandleTraits::IsValid(Handle) ? true : false; + } + + operator handle_type() const { + return Handle; + } }; -template <class HandleType, uintptr_t InvalidHandle, - class DeleterType, DeleterType D> -class ScopedHandle { - HandleType Handle; +struct CommonHandleTraits { + typedef HANDLE handle_type; -public: - ScopedHandle() : Handle(InvalidHandle) {} - ScopedHandle(HandleType handle) : Handle(handle) {} + static handle_type GetInvalid() { + return INVALID_HANDLE_VALUE; + } - ~ScopedHandle() { - if (Handle != HandleType(InvalidHandle)) - D(Handle); + static void Close(handle_type h) { + ::CloseHandle(h); } - HandleType take() { - HandleType temp = Handle; - Handle = HandleType(InvalidHandle); - return temp; + static bool IsValid(handle_type h) { + return h != GetInvalid(); } +}; - operator HandleType() const { return Handle; } +struct JobHandleTraits : CommonHandleTraits { + static handle_type GetInvalid() { + return NULL; + } +}; - ScopedHandle &operator=(HandleType handle) { - Handle = handle; - return *this; +struct CryptContextTraits : CommonHandleTraits { + typedef HCRYPTPROV handle_type; + + static handle_type GetInvalid() { + return 0; } - typedef void (*unspecified_bool_type)(); - static void unspecified_bool_true() {} + static void Close(handle_type h) { + ::CryptReleaseContext(h, 0); + } - // True if Handle is valid. - operator unspecified_bool_type() const { - return Handle == HandleType(InvalidHandle) ? 0 : unspecified_bool_true; + static bool IsValid(handle_type h) { + return h != GetInvalid(); } +}; - bool operator!() const { - return Handle == HandleType(InvalidHandle); +struct FindHandleTraits : CommonHandleTraits { + static void Close(handle_type h) { + ::FindClose(h); } }; -typedef ScopedHandle<HANDLE, uintptr_t(-1), - BOOL (WINAPI*)(HANDLE), ::FindClose> - ScopedFindHandle; +struct FileHandleTraits : CommonHandleTraits {}; + +typedef ScopedHandle<CommonHandleTraits> ScopedCommonHandle; +typedef ScopedHandle<FileHandleTraits> ScopedFileHandle; +typedef ScopedHandle<CryptContextTraits> ScopedCryptContext; +typedef ScopedHandle<FindHandleTraits> ScopedFindHandle; +typedef ScopedHandle<JobHandleTraits> ScopedJobHandle; namespace llvm { template <class T> |