diff options
author | Shih-wei Liao <sliao@google.com> | 2010-04-28 01:47:00 -0700 |
---|---|---|
committer | Shih-wei Liao <sliao@google.com> | 2010-04-28 01:47:00 -0700 |
commit | 7abe37e4aee38cc79d91dd069a37d7e91d5bef53 (patch) | |
tree | c13b26fc3d8909240f981988535c0b82dd9bf37c /lib/System | |
parent | 6037a7c3c97b651dd70e48ebe5453134713971ed (diff) | |
download | external_llvm-7abe37e4aee38cc79d91dd069a37d7e91d5bef53.zip external_llvm-7abe37e4aee38cc79d91dd069a37d7e91d5bef53.tar.gz external_llvm-7abe37e4aee38cc79d91dd069a37d7e91d5bef53.tar.bz2 |
Sync upstream to r102410.
Re-turn on sdk.
Change-Id: I91a890863989a67243b4d2dfd1ae09b843ebaeaf
Diffstat (limited to 'lib/System')
-rw-r--r-- | lib/System/Android.mk | 3 | ||||
-rw-r--r-- | lib/System/CMakeLists.txt | 2 | ||||
-rw-r--r-- | lib/System/DynamicLibrary.cpp | 60 | ||||
-rw-r--r-- | lib/System/Memory.cpp | 3 | ||||
-rw-r--r-- | lib/System/Program.cpp | 6 | ||||
-rw-r--r-- | lib/System/SearchForAddressOfSpecialSymbol.cpp | 64 | ||||
-rw-r--r-- | lib/System/Unix/Mutex.inc | 6 | ||||
-rw-r--r-- | lib/System/Unix/Path.inc | 29 | ||||
-rw-r--r-- | lib/System/Unix/Program.inc | 106 | ||||
-rw-r--r-- | lib/System/Unix/Signals.inc | 27 | ||||
-rw-r--r-- | lib/System/Valgrind.cpp | 54 | ||||
-rw-r--r-- | lib/System/Win32/Path.inc | 22 | ||||
-rw-r--r-- | lib/System/Win32/Program.inc | 34 | ||||
-rw-r--r-- | lib/System/Win32/Signals.inc | 1 |
14 files changed, 305 insertions, 112 deletions
diff --git a/lib/System/Android.mk b/lib/System/Android.mk index 3f11fc7..e80ad69 100644 --- a/lib/System/Android.mk +++ b/lib/System/Android.mk @@ -16,7 +16,8 @@ system_SRC_FILES := \ Signals.cpp \ ThreadLocal.cpp \ Threading.cpp \ - TimeValue.cpp + TimeValue.cpp \ + Valgrind.cpp # For the host # ===================================================== diff --git a/lib/System/CMakeLists.txt b/lib/System/CMakeLists.txt index a56a1f7..b43c3af 100644 --- a/lib/System/CMakeLists.txt +++ b/lib/System/CMakeLists.txt @@ -12,10 +12,12 @@ add_llvm_library(LLVMSystem Process.cpp Program.cpp RWMutex.cpp + SearchForAddressOfSpecialSymbol.cpp Signals.cpp ThreadLocal.cpp Threading.cpp TimeValue.cpp + Valgrind.cpp Unix/Alarm.inc Unix/Host.inc Unix/Memory.inc diff --git a/lib/System/DynamicLibrary.cpp b/lib/System/DynamicLibrary.cpp index 63baa6d..6f6890c 100644 --- a/lib/System/DynamicLibrary.cpp +++ b/lib/System/DynamicLibrary.cpp @@ -24,12 +24,18 @@ // Collection of symbol name/value pairs to be searched prior to any libraries. static std::map<std::string, void*> *ExplicitSymbols = 0; -static struct ExplicitSymbolsDeleter { +namespace { + +struct ExplicitSymbolsDeleter { ~ExplicitSymbolsDeleter() { if (ExplicitSymbols) delete ExplicitSymbols; } -} Dummy; +}; + +} + +static ExplicitSymbolsDeleter Dummy; void llvm::sys::DynamicLibrary::AddSymbol(const char* symbolName, void *symbolValue) { @@ -44,6 +50,7 @@ void llvm::sys::DynamicLibrary::AddSymbol(const char* symbolName, #else +#if HAVE_DLFCN_H #include <dlfcn.h> using namespace llvm; using namespace llvm::sys; @@ -68,45 +75,20 @@ bool DynamicLibrary::LoadLibraryPermanently(const char *Filename, OpenedHandles->push_back(H); return false; } +#else -static void *SearchForAddressOfSpecialSymbol(const char* symbolName) { -#define EXPLICIT_SYMBOL(SYM) \ - extern void *SYM; if (!strcmp(symbolName, #SYM)) return &SYM - - // If this is darwin, it has some funky issues, try to solve them here. Some - // important symbols are marked 'private external' which doesn't allow - // SearchForAddressOfSymbol to find them. As such, we special case them here, - // there is only a small handful of them. - -#ifdef __APPLE__ - { - EXPLICIT_SYMBOL(__ashldi3); - EXPLICIT_SYMBOL(__ashrdi3); - EXPLICIT_SYMBOL(__cmpdi2); - EXPLICIT_SYMBOL(__divdi3); - EXPLICIT_SYMBOL(__eprintf); - EXPLICIT_SYMBOL(__fixdfdi); - EXPLICIT_SYMBOL(__fixsfdi); - EXPLICIT_SYMBOL(__fixunsdfdi); - EXPLICIT_SYMBOL(__fixunssfdi); - EXPLICIT_SYMBOL(__floatdidf); - EXPLICIT_SYMBOL(__floatdisf); - EXPLICIT_SYMBOL(__lshrdi3); - EXPLICIT_SYMBOL(__moddi3); - EXPLICIT_SYMBOL(__udivdi3); - EXPLICIT_SYMBOL(__umoddi3); - } -#endif +using namespace llvm; +using namespace llvm::sys; -#ifdef __CYGWIN__ - { - EXPLICIT_SYMBOL(_alloca); - EXPLICIT_SYMBOL(__main); - } +bool DynamicLibrary::LoadLibraryPermanently(const char *Filename, + std::string *ErrMsg) { + if (ErrMsg) *ErrMsg = "dlopen() not supported on this platform"; + return true; +} #endif -#undef EXPLICIT_SYMBOL - return 0; +namespace llvm { +void *SearchForAddressOfSpecialSymbol(const char* symbolName); } void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { @@ -120,6 +102,7 @@ void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { return I->second; } +#if HAVE_DLFCN_H // Now search the libraries. if (OpenedHandles) { for (std::vector<void *>::iterator I = OpenedHandles->begin(), @@ -131,8 +114,9 @@ void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { } } } +#endif - if (void *Result = SearchForAddressOfSpecialSymbol(symbolName)) + if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName)) return Result; // This macro returns the address of a well-known, explicit symbol diff --git a/lib/System/Memory.cpp b/lib/System/Memory.cpp index e2d838d..ef23b8d 100644 --- a/lib/System/Memory.cpp +++ b/lib/System/Memory.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/System/Memory.h" +#include "llvm/System/Valgrind.h" #include "llvm/Config/config.h" namespace llvm { @@ -68,4 +69,6 @@ void llvm::sys::Memory::InvalidateInstructionCache(const void *Addr, # endif #endif // end apple + + ValgrindDiscardTranslations(Addr, Len); } diff --git a/lib/System/Program.cpp b/lib/System/Program.cpp index a3049d46..cd58c2c 100644 --- a/lib/System/Program.cpp +++ b/lib/System/Program.cpp @@ -13,8 +13,7 @@ #include "llvm/System/Program.h" #include "llvm/Config/config.h" - -namespace llvm { +using namespace llvm; using namespace sys; //===----------------------------------------------------------------------===// @@ -48,9 +47,6 @@ Program::ExecuteNoWait(const Path& path, prg.Execute(path, args, envp, redirects, memoryLimit, ErrMsg); } - -} - // Include the platform-specific parts of this class. #ifdef LLVM_ON_UNIX #include "Unix/Program.inc" diff --git a/lib/System/SearchForAddressOfSpecialSymbol.cpp b/lib/System/SearchForAddressOfSpecialSymbol.cpp new file mode 100644 index 0000000..73b484c --- /dev/null +++ b/lib/System/SearchForAddressOfSpecialSymbol.cpp @@ -0,0 +1,64 @@ +//===- SearchForAddressOfSpecialSymbol.cpp - Function addresses -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file pulls the addresses of certain symbols out of the linker. It must +// include as few header files as possible because it declares the symbols as +// void*, which would conflict with the actual symbol type if any header +// declared it. +// +//===----------------------------------------------------------------------===// + +#include <string.h> + +// Must declare the symbols in the global namespace. +static void *DoSearch(const char* symbolName) { +#define EXPLICIT_SYMBOL(SYM) \ + extern void *SYM; if (!strcmp(symbolName, #SYM)) return &SYM + + // If this is darwin, it has some funky issues, try to solve them here. Some + // important symbols are marked 'private external' which doesn't allow + // SearchForAddressOfSymbol to find them. As such, we special case them here, + // there is only a small handful of them. + +#ifdef __APPLE__ + { + EXPLICIT_SYMBOL(__ashldi3); + EXPLICIT_SYMBOL(__ashrdi3); + EXPLICIT_SYMBOL(__cmpdi2); + EXPLICIT_SYMBOL(__divdi3); + EXPLICIT_SYMBOL(__eprintf); + EXPLICIT_SYMBOL(__fixdfdi); + EXPLICIT_SYMBOL(__fixsfdi); + EXPLICIT_SYMBOL(__fixunsdfdi); + EXPLICIT_SYMBOL(__fixunssfdi); + EXPLICIT_SYMBOL(__floatdidf); + EXPLICIT_SYMBOL(__floatdisf); + EXPLICIT_SYMBOL(__lshrdi3); + EXPLICIT_SYMBOL(__moddi3); + EXPLICIT_SYMBOL(__udivdi3); + EXPLICIT_SYMBOL(__umoddi3); + } +#endif + +#ifdef __CYGWIN__ + { + EXPLICIT_SYMBOL(_alloca); + EXPLICIT_SYMBOL(__main); + } +#endif + +#undef EXPLICIT_SYMBOL + return 0; +} + +namespace llvm { +void *SearchForAddressOfSpecialSymbol(const char* symbolName) { + return DoSearch(symbolName); +} +} // namespace llvm diff --git a/lib/System/Unix/Mutex.inc b/lib/System/Unix/Mutex.inc index 10e7ecb..4a5e28d 100644 --- a/lib/System/Unix/Mutex.inc +++ b/lib/System/Unix/Mutex.inc @@ -29,12 +29,6 @@ MutexImpl::~MutexImpl() } bool -MutexImpl::MutexImpl() -{ - return true; -} - -bool MutexImpl::release() { return true; diff --git a/lib/System/Unix/Path.inc b/lib/System/Unix/Path.inc index a99720c..74596dc 100644 --- a/lib/System/Unix/Path.inc +++ b/lib/System/Unix/Path.inc @@ -454,7 +454,7 @@ Path::canWrite() const { bool Path::isRegularFile() const { - // Get the status so we can determine if its a file or directory + // Get the status so we can determine if it's a file or directory struct stat buf; if (0 != stat(path.c_str(), &buf)) @@ -736,7 +736,7 @@ Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) { bool Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const { - // Get the status so we can determine if its a file or directory + // Get the status so we can determine if it's a file or directory. struct stat buf; if (0 != stat(path.c_str(), &buf)) { MakeErrMsg(ErrStr, path + ": can't get status of file"); @@ -858,15 +858,20 @@ Path::makeUnique(bool reuse_current, std::string* ErrMsg) { // Append an XXXXXX pattern to the end of the file for use with mkstemp, // mktemp or our own implementation. - std::string Buf(path); + // This uses std::vector instead of SmallVector to avoid a dependence on + // libSupport. And performance isn't critical here. + std::vector<char> Buf; + Buf.resize(path.size()+8); + char *FNBuffer = &Buf[0]; + path.copy(FNBuffer,path.size()); if (isDirectory()) - Buf += "/XXXXXX"; + strcpy(FNBuffer+path.size(), "/XXXXXX"); else - Buf += "-XXXXXX"; + strcpy(FNBuffer+path.size(), "-XXXXXX"); #if defined(HAVE_MKSTEMP) int TempFD; - if ((TempFD = mkstemp((char*)Buf.c_str())) == -1) + if ((TempFD = mkstemp(FNBuffer)) == -1) return MakeErrMsg(ErrMsg, path + ": can't make unique filename"); // We don't need to hold the temp file descriptor... we will trust that no one @@ -874,21 +879,21 @@ Path::makeUnique(bool reuse_current, std::string* ErrMsg) { close(TempFD); // Save the name - path = Buf; + path = FNBuffer; #elif defined(HAVE_MKTEMP) // If we don't have mkstemp, use the old and obsolete mktemp function. - if (mktemp(Buf.c_str()) == 0) + if (mktemp(FNBuffer) == 0) return MakeErrMsg(ErrMsg, path + ": can't make unique filename"); // Save the name - path = Buf; + path = FNBuffer; #else // Okay, looks like we have to do it all by our lonesome. static unsigned FCounter = 0; unsigned offset = path.size() + 1; - while (FCounter < 999999 && exists()) { - sprintf(Buf.data()+offset, "%06u", ++FCounter); - path = Buf; + while ( FCounter < 999999 && exists()) { + sprintf(FNBuffer+offset,"%06u",++FCounter); + path = FNBuffer; } if (FCounter > 999999) return MakeErrMsg(ErrMsg, diff --git a/lib/System/Unix/Program.inc b/lib/System/Unix/Program.inc index c10498a..358415f 100644 --- a/lib/System/Unix/Program.inc +++ b/lib/System/Unix/Program.inc @@ -30,6 +30,14 @@ #if HAVE_FCNTL_H #include <fcntl.h> #endif +#ifdef HAVE_POSIX_SPAWN +#include <spawn.h> +#if !defined(__APPLE__) + extern char **environ; +#else +#include <crt_externs.h> // _NSGetEnviron +#endif +#endif namespace llvm { using namespace sys; @@ -94,33 +102,52 @@ Program::FindProgramByName(const std::string& progName) { } static bool RedirectIO(const Path *Path, int FD, std::string* ErrMsg) { - if (Path == 0) - // Noop + if (Path == 0) // Noop return false; - std::string File; + const char *File; if (Path->isEmpty()) // Redirect empty paths to /dev/null File = "/dev/null"; else - File = Path->str(); + File = Path->c_str(); // Open the file - int InFD = open(File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666); + int InFD = open(File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666); if (InFD == -1) { - MakeErrMsg(ErrMsg, "Cannot open file '" + File + "' for " + MakeErrMsg(ErrMsg, "Cannot open file '" + std::string(File) + "' for " + (FD == 0 ? "input" : "output")); return true; } // Install it as the requested FD - if (-1 == dup2(InFD, FD)) { + if (dup2(InFD, FD) == -1) { MakeErrMsg(ErrMsg, "Cannot dup2"); + close(InFD); return true; } close(InFD); // Close the original FD return false; } +#ifdef HAVE_POSIX_SPAWN +static bool RedirectIO_PS(const Path *Path, int FD, std::string *ErrMsg, + posix_spawn_file_actions_t &FileActions) { + if (Path == 0) // Noop + return false; + const char *File; + if (Path->isEmpty()) + // Redirect empty paths to /dev/null + File = "/dev/null"; + else + File = Path->c_str(); + + if (int Err = posix_spawn_file_actions_addopen(&FileActions, FD, + File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666)) + return MakeErrMsg(ErrMsg, "Cannot dup2", Err); + return false; +} +#endif + static void TimeOutHandler(int Sig) { } @@ -150,13 +177,55 @@ static void SetMemoryLimits (unsigned size) } bool -Program::Execute(const Path& path, - const char** args, - const char** envp, - const Path** redirects, - unsigned memoryLimit, - std::string* ErrMsg) -{ +Program::Execute(const Path &path, const char **args, const char **envp, + const Path **redirects, unsigned memoryLimit, + std::string *ErrMsg) { + // If this OS has posix_spawn and there is no memory limit being implied, use + // posix_spawn. It is more efficient than fork/exec. +#ifdef HAVE_POSIX_SPAWN + if (memoryLimit == 0) { + posix_spawn_file_actions_t FileActions; + posix_spawn_file_actions_init(&FileActions); + + if (redirects) { + // Redirect stdin/stdout. + if (RedirectIO_PS(redirects[0], 0, ErrMsg, FileActions) || + RedirectIO_PS(redirects[1], 1, ErrMsg, FileActions)) + return false; + if (redirects[1] == 0 || redirects[2] == 0 || + *redirects[1] != *redirects[2]) { + // Just redirect stderr + if (RedirectIO_PS(redirects[2], 2, ErrMsg, FileActions)) return false; + } else { + // If stdout and stderr should go to the same place, redirect stderr + // to the FD already open for stdout. + if (int Err = posix_spawn_file_actions_adddup2(&FileActions, 1, 2)) + return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err); + } + } + + if (!envp) +#if !defined(__APPLE__) + envp = const_cast<const char **>(environ); +#else + // environ is missing in dylibs. + envp = const_cast<const char **>(*_NSGetEnviron()); +#endif + + pid_t PID; + int Err = posix_spawn(&PID, path.c_str(), &FileActions, /*attrp*/0, + const_cast<char **>(args), const_cast<char **>(envp)); + + posix_spawn_file_actions_destroy(&FileActions); + + if (Err) + return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err); + + Data_ = reinterpret_cast<void*>(PID); + return true; + } +#endif + if (!path.canExecute()) { if (ErrMsg) *ErrMsg = path.str() + " is not executable"; @@ -200,9 +269,12 @@ Program::Execute(const Path& path, // Execute! if (envp != 0) - execve(path.c_str(), (char**)args, (char**)envp); + execve(path.c_str(), + const_cast<char **>(args), + const_cast<char **>(envp)); else - execv(path.c_str(), (char**)args); + execv(path.c_str(), + const_cast<char **>(args)); // If the execve() failed, we should exit. Follow Unix protocol and // return 127 if the executable was not found, and 126 otherwise. // Use _exit rather than exit so that atexit functions and static @@ -238,7 +310,9 @@ Program::Wait(unsigned secondsToWait, // fact of having a handler at all causes the wait below to return with EINTR, // unlike if we used SIG_IGN. if (secondsToWait) { +#ifndef __HAIKU__ Act.sa_sigaction = 0; +#endif Act.sa_handler = TimeOutHandler; sigemptyset(&Act.sa_mask); Act.sa_flags = 0; diff --git a/lib/System/Unix/Signals.inc b/lib/System/Unix/Signals.inc index c8ec68a..56bf9e7 100644 --- a/lib/System/Unix/Signals.inc +++ b/lib/System/Unix/Signals.inc @@ -39,8 +39,8 @@ static SmartMutex<true> SignalsMutex; /// InterruptFunction - The function to call if ctrl-c is pressed. static void (*InterruptFunction)() = 0; -static std::vector<sys::Path> *FilesToRemove = 0; -static std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0; +static std::vector<sys::Path> FilesToRemove; +static std::vector<std::pair<void(*)(void*), void*> > CallBacksToRun; // IntSigs - Signals that may interrupt the program at any time. static const int IntSigs[] = { @@ -126,11 +126,10 @@ static RETSIGTYPE SignalHandler(int Sig) { sigprocmask(SIG_UNBLOCK, &SigMask, 0); SignalsMutex.acquire(); - if (FilesToRemove != 0) - while (!FilesToRemove->empty()) { - FilesToRemove->back().eraseFromDisk(true); - FilesToRemove->pop_back(); - } + while (!FilesToRemove.empty()) { + FilesToRemove.back().eraseFromDisk(true); + FilesToRemove.pop_back(); + } if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd) { if (InterruptFunction) { @@ -149,9 +148,8 @@ static RETSIGTYPE SignalHandler(int Sig) { SignalsMutex.release(); // Otherwise if it is a fault (like SEGV) run any handler. - if (CallBacksToRun) - for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i) - (*CallBacksToRun)[i].first((*CallBacksToRun)[i].second); + for (unsigned i = 0, e = CallBacksToRun.size(); i != e; ++i) + CallBacksToRun[i].first(CallBacksToRun[i].second); } @@ -167,10 +165,7 @@ void llvm::sys::SetInterruptFunction(void (*IF)()) { bool llvm::sys::RemoveFileOnSignal(const sys::Path &Filename, std::string* ErrMsg) { SignalsMutex.acquire(); - if (FilesToRemove == 0) - FilesToRemove = new std::vector<sys::Path>(); - - FilesToRemove->push_back(Filename); + FilesToRemove.push_back(Filename); SignalsMutex.release(); @@ -182,9 +177,7 @@ bool llvm::sys::RemoveFileOnSignal(const sys::Path &Filename, /// to the process. The handler can have a cookie passed to it to identify /// what instance of the handler it is. void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) { - if (CallBacksToRun == 0) - CallBacksToRun = new std::vector<std::pair<void(*)(void*), void*> >(); - CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie)); + CallBacksToRun.push_back(std::make_pair(FnPtr, Cookie)); RegisterHandlers(); } diff --git a/lib/System/Valgrind.cpp b/lib/System/Valgrind.cpp new file mode 100644 index 0000000..c76cfe4 --- /dev/null +++ b/lib/System/Valgrind.cpp @@ -0,0 +1,54 @@ +//===-- Valgrind.cpp - Implement Valgrind communication ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Defines Valgrind communication methods, if HAVE_VALGRIND_VALGRIND_H is +// defined. If we have valgrind.h but valgrind isn't running, its macros are +// no-ops. +// +//===----------------------------------------------------------------------===// + +#include "llvm/System/Valgrind.h" +#include "llvm/Config/config.h" + +#if HAVE_VALGRIND_VALGRIND_H +#include <valgrind/valgrind.h> + +static bool InitNotUnderValgrind() { + return !RUNNING_ON_VALGRIND; +} + +// This bool is negated from what we'd expect because code may run before it +// gets initialized. If that happens, it will appear to be 0 (false), and we +// want that to cause the rest of the code in this file to run the +// Valgrind-provided macros. +static const bool NotUnderValgrind = InitNotUnderValgrind(); + +bool llvm::sys::RunningOnValgrind() { + if (NotUnderValgrind) + return false; + return RUNNING_ON_VALGRIND; +} + +void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) { + if (NotUnderValgrind) + return; + + VALGRIND_DISCARD_TRANSLATIONS(Addr, Len); +} + +#else // !HAVE_VALGRIND_VALGRIND_H + +bool llvm::sys::RunningOnValgrind() { + return false; +} + +void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) { +} + +#endif // !HAVE_VALGRIND_VALGRIND_H diff --git a/lib/System/Win32/Path.inc b/lib/System/Win32/Path.inc index b5f6374..5a0052f 100644 --- a/lib/System/Win32/Path.inc +++ b/lib/System/Win32/Path.inc @@ -126,7 +126,7 @@ Path::isValid() const { } void Path::makeAbsolute() { - TCHAR FullPath[MAX_PATH + 1] = {0}; + TCHAR FullPath[MAX_PATH + 1] = {0}; LPTSTR FilePart = NULL; DWORD RetLength = ::GetFullPathNameA(path.c_str(), @@ -161,7 +161,7 @@ Path::isAbsolute(const char *NameStart, unsigned NameLen) { } } -bool +bool Path::isAbsolute() const { // FIXME: This does not handle correctly an absolute path starting from // a drive letter or in UNC format. @@ -174,9 +174,9 @@ Path::isAbsolute() const { default: return path[0] == '/' || (path[1] == ':' && path[2] == '/'); } -} +} -static Path *TempDirectory = NULL; +static Path *TempDirectory; Path Path::GetTemporaryDirectory(std::string* ErrMsg) { @@ -266,7 +266,7 @@ Path Path::GetCurrentDirectory() { char pathname[MAX_PATH]; ::GetCurrentDirectoryA(MAX_PATH,pathname); - return Path(pathname); + return Path(pathname); } /// GetMainExecutable - Return the path to the main executable, given the @@ -448,7 +448,7 @@ Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const { MakeErrMsg(ErrMsg, path + ": can't get status of file"); return true; } - + if (!(fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { if (ErrMsg) *ErrMsg = path + ": not a directory"; @@ -617,7 +617,7 @@ Path::createDirectoryOnDisk(bool create_parents, std::string* ErrMsg) { *next = 0; if (!CreateDirectory(pathname, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) - return MakeErrMsg(ErrMsg, + return MakeErrMsg(ErrMsg, std::string(pathname) + ": Can't create directory: "); *next++ = '/'; } @@ -649,7 +649,7 @@ Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const { WIN32_FILE_ATTRIBUTE_DATA fi; if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) return true; - + if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // If it doesn't exist, we're done. if (!exists()) @@ -706,7 +706,7 @@ Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const { pathname[lastchar] = 0; if (!RemoveDirectory(pathname)) - return MakeErrMsg(ErrStr, + return MakeErrMsg(ErrStr, std::string(pathname) + ": Can't destroy directory: "); return false; } else { @@ -753,7 +753,7 @@ bool Path::getMagicNumber(std::string& Magic, unsigned len) const { bool Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) { if (!MoveFileEx(path.c_str(), newName.c_str(), MOVEFILE_REPLACE_EXISTING)) - return MakeErrMsg(ErrMsg, "Can't move '" + path + "' to '" + newName.path + return MakeErrMsg(ErrMsg, "Can't move '" + path + "' to '" + newName.path + "': "); return false; } @@ -764,7 +764,7 @@ Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrMsg) const { if (!si.isFile) { return true; } - + HANDLE h = CreateFile(path.c_str(), FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, diff --git a/lib/System/Win32/Program.inc b/lib/System/Win32/Program.inc index a3b40d0..16bb28e 100644 --- a/lib/System/Win32/Program.inc +++ b/lib/System/Win32/Program.inc @@ -138,6 +138,24 @@ static bool ArgNeedsQuotes(const char *Str) { return Str[0] == '\0' || strchr(Str, ' ') != 0; } + +/// ArgLenWithQuotes - Check whether argument needs to be quoted when calling +/// CreateProcess and returns length of quoted arg with escaped quotes +static unsigned int ArgLenWithQuotes(const char *Str) { + unsigned int len = ArgNeedsQuotes(Str) ? 2 : 0; + + while (*Str != '\0') { + if (*Str == '\"') + ++len; + + ++len; + ++Str; + } + + return len; +} + + bool Program::Execute(const Path& path, const char** args, @@ -165,9 +183,7 @@ Program::Execute(const Path& path, // First, determine the length of the command line. unsigned len = 0; for (unsigned i = 0; args[i]; i++) { - len += strlen(args[i]) + 1; - if (ArgNeedsQuotes(args[i])) - len += 2; + len += ArgLenWithQuotes(args[i]) + 1; } // Now build the command line. @@ -176,12 +192,18 @@ Program::Execute(const Path& path, for (unsigned i = 0; args[i]; i++) { const char *arg = args[i]; - size_t len = strlen(arg); + bool needsQuoting = ArgNeedsQuotes(arg); if (needsQuoting) *p++ = '"'; - memcpy(p, arg, len); - p += len; + + while (*arg != '\0') { + if (*arg == '\"') + *p++ = '\\'; + + *p++ = *arg++; + } + if (needsQuoting) *p++ = '"'; *p++ = ' '; diff --git a/lib/System/Win32/Signals.inc b/lib/System/Win32/Signals.inc index dba2218..f2b72ca 100644 --- a/lib/System/Win32/Signals.inc +++ b/lib/System/Win32/Signals.inc @@ -163,6 +163,7 @@ void sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) { CallBacksToRun = new std::vector<std::pair<void(*)(void*), void*> >(); CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie)); RegisterHandler(); + LeaveCriticalSection(&CriticalSection); } } |