Mercurial > hg > Members > tobaru > cbc > CbC_llvm
diff lib/Support/Unix/Process.inc @ 83:60c9769439b8
LLVM 3.7
author | Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 18 Feb 2015 14:55:36 +0900 |
parents | 54457678186b |
children | afa8332a0e37 |
line wrap: on
line diff
--- a/lib/Support/Unix/Process.inc Mon Sep 08 22:07:30 2014 +0900 +++ b/lib/Support/Unix/Process.inc Wed Feb 18 14:55:36 2015 +0900 @@ -14,15 +14,25 @@ #include "Unix.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Mutex.h" #include "llvm/Support/MutexGuard.h" #include "llvm/Support/TimeValue.h" +#if HAVE_FCNTL_H +#include <fcntl.h> +#endif #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #endif #ifdef HAVE_SYS_RESOURCE_H #include <sys/resource.h> #endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif +#if HAVE_SIGNAL_H +#include <signal.h> +#endif // DragonFlyBSD, OpenBSD, and Bitrig have deprecated <malloc.h> for // <stdlib.h> instead. Unix.h includes this for us already. #if defined(HAVE_MALLOC_H) && !defined(__DragonFly__) && \ @@ -47,10 +57,6 @@ using namespace llvm; using namespace sys; -process::id_type self_process::get_id() { - return getpid(); -} - static std::pair<TimeValue, TimeValue> getRUsageTimes() { #if defined(HAVE_GETRUSAGE) struct rusage RU; @@ -70,43 +76,19 @@ #endif } -TimeValue self_process::get_user_time() const { -#if _POSIX_TIMERS > 0 && _POSIX_CPUTIME > 0 - // Try to get a high resolution CPU timer. - struct timespec TS; - if (::clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &TS) == 0) - return TimeValue(static_cast<TimeValue::SecondsType>(TS.tv_sec), - static_cast<TimeValue::NanoSecondsType>(TS.tv_nsec)); -#endif - - // Otherwise fall back to rusage based timing. - return getRUsageTimes().first; -} - -TimeValue self_process::get_system_time() const { - // We can only collect system time by inspecting the results of getrusage. - return getRUsageTimes().second; -} - // On Cygwin, getpagesize() returns 64k(AllocationGranularity) and // offset in mmap(3) should be aligned to the AllocationGranularity. -static unsigned getPageSize() { +unsigned Process::getPageSize() { #if defined(HAVE_GETPAGESIZE) - const int page_size = ::getpagesize(); + static const int page_size = ::getpagesize(); #elif defined(HAVE_SYSCONF) - long page_size = ::sysconf(_SC_PAGE_SIZE); + static long page_size = ::sysconf(_SC_PAGE_SIZE); #else #warning Cannot get the page size on this machine #endif return static_cast<unsigned>(page_size); } -// This constructor guaranteed to be run exactly once on a single thread, and -// sets up various process invariants that can be queried cheaply from then on. -self_process::self_process() : PageSize(getPageSize()) { -} - - size_t Process::GetMallocUsage() { #if defined(HAVE_MALLINFO) struct mallinfo mi; @@ -198,6 +180,97 @@ return std::error_code(); } +namespace { +class FDCloser { +public: + FDCloser(int &FD) : FD(FD), KeepOpen(false) {} + void keepOpen() { KeepOpen = true; } + ~FDCloser() { + if (!KeepOpen && FD >= 0) + ::close(FD); + } + +private: + FDCloser(const FDCloser &) = delete; + void operator=(const FDCloser &) = delete; + + int &FD; + bool KeepOpen; +}; +} + +std::error_code Process::FixupStandardFileDescriptors() { + int NullFD = -1; + FDCloser FDC(NullFD); + const int StandardFDs[] = {STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}; + for (int StandardFD : StandardFDs) { + struct stat st; + errno = 0; + while (fstat(StandardFD, &st) < 0) { + assert(errno && "expected errno to be set if fstat failed!"); + // fstat should return EBADF if the file descriptor is closed. + if (errno == EBADF) + break; + // retry fstat if we got EINTR, otherwise bubble up the failure. + if (errno != EINTR) + return std::error_code(errno, std::generic_category()); + } + // if fstat succeeds, move on to the next FD. + if (!errno) + continue; + assert(errno == EBADF && "expected errno to have EBADF at this point!"); + + if (NullFD < 0) { + while ((NullFD = open("/dev/null", O_RDWR)) < 0) { + if (errno == EINTR) + continue; + return std::error_code(errno, std::generic_category()); + } + } + + if (NullFD == StandardFD) + FDC.keepOpen(); + else if (dup2(NullFD, StandardFD) < 0) + return std::error_code(errno, std::generic_category()); + } + return std::error_code(); +} + +std::error_code Process::SafelyCloseFileDescriptor(int FD) { + // Create a signal set filled with *all* signals. + sigset_t FullSet; + if (sigfillset(&FullSet) < 0) + return std::error_code(errno, std::generic_category()); + // Atomically swap our current signal mask with a full mask. + sigset_t SavedSet; +#if LLVM_ENABLE_THREADS + if (int EC = pthread_sigmask(SIG_SETMASK, &FullSet, &SavedSet)) + return std::error_code(EC, std::generic_category()); +#else + if (sigprocmask(SIG_SETMASK, &FullSet, &SavedSet) < 0) + return std::error_code(errno, std::generic_category()); +#endif + // Attempt to close the file descriptor. + // We need to save the error, if one occurs, because our subsequent call to + // pthread_sigmask might tamper with errno. + int ErrnoFromClose = 0; + if (::close(FD) < 0) + ErrnoFromClose = errno; + // Restore the signal mask back to what we saved earlier. + int EC = 0; +#if LLVM_ENABLE_THREADS + EC = pthread_sigmask(SIG_SETMASK, &SavedSet, nullptr); +#else + if (sigprocmask(SIG_SETMASK, &SavedSet, nullptr) < 0) + EC = errno; +#endif + // The error code from close takes precedence over the one from + // pthread_sigmask. + if (ErrnoFromClose) + return std::error_code(ErrnoFromClose, std::generic_category()); + return std::error_code(EC, std::generic_category()); +} + bool Process::StandardInIsUserInput() { return FileDescriptorIsDisplayed(STDIN_FILENO); } @@ -263,11 +336,14 @@ extern "C" int tigetnum(char *capname); #endif +#ifdef HAVE_TERMINFO +static ManagedStatic<sys::Mutex> TermColorMutex; +#endif + static bool terminalHasColors(int fd) { #ifdef HAVE_TERMINFO // First, acquire a global lock because these C routines are thread hostile. - static sys::Mutex M; - MutexGuard G(M); + MutexGuard G(*TermColorMutex); int errret = 0; if (setupterm((char *)nullptr, fd, &errret) != 0)