diff options
Diffstat (limited to 'third_party/nix/src/libmain')
-rw-r--r-- | third_party/nix/src/libmain/CMakeLists.txt | 33 | ||||
-rw-r--r-- | third_party/nix/src/libmain/common-args.cc | 56 | ||||
-rw-r--r-- | third_party/nix/src/libmain/common-args.hh | 27 | ||||
-rw-r--r-- | third_party/nix/src/libmain/nix-main.pc.in | 9 | ||||
-rw-r--r-- | third_party/nix/src/libmain/shared.cc | 386 | ||||
-rw-r--r-- | third_party/nix/src/libmain/shared.hh | 134 | ||||
-rw-r--r-- | third_party/nix/src/libmain/stack.cc | 75 |
7 files changed, 0 insertions, 720 deletions
diff --git a/third_party/nix/src/libmain/CMakeLists.txt b/third_party/nix/src/libmain/CMakeLists.txt deleted file mode 100644 index a95128c1318f..000000000000 --- a/third_party/nix/src/libmain/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -# -*- mode: cmake; -*- -add_library(nixmain SHARED) -set_property(TARGET nixmain PROPERTY CXX_STANDARD 17) -include_directories(${PROJECT_BINARY_DIR}) # for config.h -target_include_directories(nixmain PUBLIC "${nix_SOURCE_DIR}/src") - -set(HEADER_FILES - common-args.hh - shared.hh -) - -target_sources(nixmain - PUBLIC - ${HEADER_FILES} - PRIVATE - common-args.cc - shared.cc - stack.cc -) - -target_link_libraries(nixmain - nixstore - nixutil - - absl::strings - glog -) - -configure_file("nix-main.pc.in" "${PROJECT_BINARY_DIR}/nix-main.pc" @ONLY) -INSTALL(FILES "${PROJECT_BINARY_DIR}/nix-main.pc" DESTINATION "${PKGCONFIG_INSTALL_DIR}") - -INSTALL(FILES ${HEADER_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/nix/libmain) -INSTALL(TARGETS nixmain DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/third_party/nix/src/libmain/common-args.cc b/third_party/nix/src/libmain/common-args.cc deleted file mode 100644 index 729e026f1990..000000000000 --- a/third_party/nix/src/libmain/common-args.cc +++ /dev/null @@ -1,56 +0,0 @@ -#include "libmain/common-args.hh" - -#include <glog/logging.h> - -#include "libstore/globals.hh" - -namespace nix { - -MixCommonArgs::MixCommonArgs(const std::string& programName) - : programName(programName) { - mkFlag() - .longName("verbose") - .shortName('v') - .description("increase verbosity level") - .handler([]() { - FLAGS_stderrthreshold = google::GLOG_INFO; - FLAGS_v += 1; - }); - - mkFlag() - .longName("quiet") - .description("silence all log output") - .handler([]() { FLAGS_stderrthreshold = google::GLOG_FATAL; }); - - mkFlag() - .longName("option") - .labels({"name", "value"}) - .description("set a Nix configuration option (overriding nix.conf)") - .arity(2) - .handler([](std::vector<std::string> ss) { - try { - globalConfig.set(ss[0], ss[1]); - } catch (UsageError& e) { - LOG(WARNING) << e.what(); - } - }); - - mkFlag() - .longName("max-jobs") - .shortName('j') - .label("jobs") - .description("maximum number of parallel builds") - .handler([=](const std::string& s) { settings.set("max-jobs", s); }); - - std::string cat = "config"; - globalConfig.convertToArgs(*this, cat); - - // Backward compatibility hack: nix-env already had a --system flag. - if (programName == "nix-env") { - longFlags.erase("system"); - } - - hiddenCategories.insert(cat); -} - -} // namespace nix diff --git a/third_party/nix/src/libmain/common-args.hh b/third_party/nix/src/libmain/common-args.hh deleted file mode 100644 index f1c7c8481323..000000000000 --- a/third_party/nix/src/libmain/common-args.hh +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "libutil/args.hh" - -namespace nix { - -struct MixCommonArgs : virtual Args { - std::string programName; - MixCommonArgs(const std::string& programName); -}; - -struct MixDryRun : virtual Args { - bool dryRun = false; - - MixDryRun() { - mkFlag(0, "dry-run", "show what this command would do without doing it", - &dryRun); - } -}; - -struct MixJSON : virtual Args { - bool json = false; - - MixJSON() { mkFlag(0, "json", "produce JSON output", &json); } -}; - -} // namespace nix diff --git a/third_party/nix/src/libmain/nix-main.pc.in b/third_party/nix/src/libmain/nix-main.pc.in deleted file mode 100644 index 9876a3d1b7ae..000000000000 --- a/third_party/nix/src/libmain/nix-main.pc.in +++ /dev/null @@ -1,9 +0,0 @@ -prefix=@CMAKE_INSTALL_PREFIX@ -libdir=@CMAKE_INSTALL_FULL_LIBDIR@ -includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ - -Name: Nix -Description: Nix Package Manager -Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -lnixmain -Cflags: -I${includedir}/nix diff --git a/third_party/nix/src/libmain/shared.cc b/third_party/nix/src/libmain/shared.cc deleted file mode 100644 index 331ea6b3a9d2..000000000000 --- a/third_party/nix/src/libmain/shared.cc +++ /dev/null @@ -1,386 +0,0 @@ -#include "libmain/shared.hh" - -#include <algorithm> -#include <cctype> -#include <csignal> -#include <cstdlib> -#include <exception> -#include <iostream> -#include <mutex> -#include <utility> - -#include <glog/logging.h> -#include <openssl/crypto.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <unistd.h> - -#include "libstore/globals.hh" -#include "libstore/store-api.hh" -#include "libutil/util.hh" - -namespace nix { - -static bool gcWarning = true; - -void printGCWarning() { - if (!gcWarning) { - return; - } - - static bool haveWarned = false; - if (!haveWarned) { - haveWarned = true; - LOG(WARNING) << "you did not specify '--add-root'; " - << "the result might be removed by the garbage collector"; - } -} - -void printMissing(const ref<Store>& store, const PathSet& paths) { - unsigned long long downloadSize; - unsigned long long narSize; - PathSet willBuild; - PathSet willSubstitute; - PathSet unknown; - store->queryMissing(paths, willBuild, willSubstitute, unknown, downloadSize, - narSize); - printMissing(store, willBuild, willSubstitute, unknown, downloadSize, - narSize); -} - -void printMissing(const ref<Store>& store, const PathSet& willBuild, - const PathSet& willSubstitute, const PathSet& unknown, - unsigned long long downloadSize, unsigned long long narSize) { - if (!willBuild.empty()) { - LOG(INFO) << "these derivations will be built:"; - Paths sorted = store->topoSortPaths(willBuild); - reverse(sorted.begin(), sorted.end()); - for (auto& i : sorted) { - LOG(INFO) << " " << i; - } - } - - if (!willSubstitute.empty()) { - LOG(INFO) << "these paths will be fetched (" - << (downloadSize / (1024.0 * 1024.0)) << " MiB download, " - << (narSize / (1024.0 * 1024.0)) << "MiB unpacked):"; - - for (auto& i : willSubstitute) { - LOG(INFO) << i; - } - } - - if (!unknown.empty()) { - LOG(INFO) << "don't know how to build these paths" - << (settings.readOnlyMode - ? " (may be caused by read-only store access)" - : "") - << ":"; - - for (auto& i : unknown) { - LOG(INFO) << i; - } - } -} - -std::string getArg(const std::string& opt, Strings::iterator& i, - const Strings::iterator& end) { - ++i; - if (i == end) { - throw UsageError(format("'%1%' requires an argument") % opt); - } - - return *i; -} - -#if OPENSSL_VERSION_NUMBER < 0x10101000L -/* OpenSSL is not thread-safe by default - it will randomly crash - unless the user supplies a mutex locking function. So let's do - that. */ -static std::vector<std::mutex> opensslLocks; - -static void opensslLockCallback(int mode, int type, const char* file, - int line) { - if (mode & CRYPTO_LOCK) - opensslLocks[type].lock(); - else - opensslLocks[type].unlock(); -} -#endif - -static void sigHandler(int signo) {} - -void initNix() { - /* Turn on buffering for cerr. */ -#if HAVE_PUBSETBUF - static char buf[1024]; - std::cerr.rdbuf()->pubsetbuf(buf, sizeof(buf)); -#endif - -#if OPENSSL_VERSION_NUMBER < 0x10101000L - /* Initialise OpenSSL locking. */ - opensslLocks = std::vector<std::mutex>(CRYPTO_num_locks()); - CRYPTO_set_locking_callback(opensslLockCallback); -#endif - - loadConfFile(); - - startSignalHandlerThread(); - - /* Reset SIGCHLD to its default. */ - struct sigaction act; - sigemptyset(&act.sa_mask); - act.sa_handler = SIG_DFL; - act.sa_flags = 0; - if (sigaction(SIGCHLD, &act, nullptr) != 0) { - throw SysError("resetting SIGCHLD"); - } - - /* Install a dummy SIGUSR1 handler for use with pthread_kill(). */ - act.sa_handler = sigHandler; - if (sigaction(SIGUSR1, &act, nullptr) != 0) { - throw SysError("handling SIGUSR1"); - } - - /* Register a SIGSEGV handler to detect stack overflows. */ - detectStackOverflow(); - - /* There is no privacy in the Nix system ;-) At least not for - now. In particular, store objects should be readable by - everybody. */ - umask(0022); - - /* Initialise the PRNG. */ - struct timeval tv; - gettimeofday(&tv, nullptr); - srandom(tv.tv_usec); -} - -LegacyArgs::LegacyArgs( - const std::string& programName, - std::function<bool(Strings::iterator& arg, const Strings::iterator& end)> - parseArg) - : MixCommonArgs(programName), parseArg(std::move(parseArg)) { - mkFlag() - .longName("no-build-output") - .shortName('Q') - .description("do not show build output") - .set(&settings.verboseBuild, false); - - mkFlag() - .longName("keep-failed") - .shortName('K') - .description("keep temporary directories of failed builds") - .set(&(bool&)settings.keepFailed, true); - - mkFlag() - .longName("keep-going") - .shortName('k') - .description("keep going after a build fails") - .set(&(bool&)settings.keepGoing, true); - - mkFlag() - .longName("fallback") - .description("build from source if substitution fails") - .set(&(bool&)settings.tryFallback, true); - - auto intSettingAlias = [&](char shortName, const std::string& longName, - const std::string& description, - const std::string& dest) { - mkFlag<unsigned int>(shortName, longName, description, [=](unsigned int n) { - settings.set(dest, std::to_string(n)); - }); - }; - - intSettingAlias(0, "cores", - "maximum number of CPU cores to use inside a build", "cores"); - intSettingAlias(0, "max-silent-time", - "number of seconds of silence before a build is killed", - "max-silent-time"); - intSettingAlias(0, "timeout", "number of seconds before a build is killed", - "timeout"); - - mkFlag(0, "readonly-mode", "do not write to the Nix store", - &settings.readOnlyMode); - - mkFlag(0, "no-gc-warning", "disable warning about not using '--add-root'", - &gcWarning, false); - - mkFlag() - .longName("store") - .label("store-uri") - .description("URI of the Nix store to use") - .dest(&(std::string&)settings.storeUri); -} - -bool LegacyArgs::processFlag(Strings::iterator& pos, Strings::iterator end) { - if (MixCommonArgs::processFlag(pos, end)) { - return true; - } - bool res = parseArg(pos, end); - if (res) { - ++pos; - } - return res; -} - -bool LegacyArgs::processArgs(const Strings& args, bool finish) { - if (args.empty()) { - return true; - } - assert(args.size() == 1); - Strings ss(args); - auto pos = ss.begin(); - if (!parseArg(pos, ss.end())) { - throw UsageError(format("unexpected argument '%1%'") % args.front()); - } - return true; -} - -void parseCmdLine( - int argc, char** argv, - std::function<bool(Strings::iterator& arg, const Strings::iterator& end)> - parseArg) { - parseCmdLine(baseNameOf(argv[0]), argvToStrings(argc, argv), - std::move(parseArg)); -} - -void parseCmdLine( - const std::string& programName, const Strings& args, - std::function<bool(Strings::iterator& arg, const Strings::iterator& end)> - parseArg) { - LegacyArgs(programName, std::move(parseArg)).parseCmdline(args); -} - -void printVersion(const std::string& programName) { - std::cout << format("%1% (Tvix) %2%") % programName % nixVersion << std::endl; - - // TODO(tazjin): figure out what the fuck this is - /*if (verbosity > lvlInfo) { - Strings cfg; -#if HAVE_BOEHMGC - cfg.push_back("gc"); -#endif -#if HAVE_SODIUM - cfg.push_back("signed-caches"); -#endif - std::cout << "Features: " << concatStringsSep(", ", cfg) << "\n"; - std::cout << "Configuration file: " << settings.nixConfDir + "/nix.conf" - << "\n"; - std::cout << "Store directory: " << settings.nixStore << "\n"; - std::cout << "State directory: " << settings.nixStateDir << "\n"; - } */ - throw Exit(); -} - -void showManPage(const std::string& name) { - restoreSignals(); - setenv("MANPATH", settings.nixManDir.c_str(), 1); - execlp("man", "man", name.c_str(), nullptr); - throw SysError(format("command 'man %1%' failed") % name.c_str()); -} - -int handleExceptions(const std::string& programName, - const std::function<void()>& fun) { - ReceiveInterrupts receiveInterrupts; // FIXME: need better place for this - - std::string error = ANSI_RED "error:" ANSI_NORMAL " "; - try { - try { - fun(); - } catch (...) { - /* Subtle: we have to make sure that any `interrupted' - condition is discharged before we reach printMsg() - below, since otherwise it will throw an (uncaught) - exception. */ - setInterruptThrown(); - throw; - } - } catch (Exit& e) { - return e.status; - } catch (UsageError& e) { - LOG(INFO) << e.what(); - LOG(INFO) << "Try '" << programName << " --help' for more information."; - return 1; - } catch (BaseError& e) { - LOG(ERROR) << error << (settings.showTrace ? e.prefix() : "") << e.msg(); - if (!e.prefix().empty() && !settings.showTrace) { - LOG(INFO) << "(use '--show-trace' to show detailed location information)"; - } - return static_cast<int>(e.status); - } catch (std::bad_alloc& e) { - LOG(ERROR) << error << "failed to allocate: " << e.what(); - return 1; - } catch (std::exception& e) { - LOG(ERROR) << error << e.what(); - return 1; - } - - return 0; -} - -RunPager::RunPager() { - if (isatty(STDOUT_FILENO) == 0) { - return; - } - char* pager = getenv("NIX_PAGER"); - if (pager == nullptr) { - pager = getenv("PAGER"); - } - if (pager && (std::string(pager) == "" || std::string(pager) == "cat")) { - return; - } - - Pipe toPager; - toPager.create(); - - pid = startProcess([&]() { - if (dup2(toPager.readSide.get(), STDIN_FILENO) == -1) { - throw SysError("dupping stdin"); - } - if (getenv("LESS") == nullptr) { - setenv("LESS", "FRSXMK", 1); - } - restoreSignals(); - if (pager != nullptr) { - execl("/bin/sh", "sh", "-c", pager, nullptr); - } - execlp("pager", "pager", nullptr); - execlp("less", "less", nullptr); - execlp("more", "more", nullptr); - throw SysError(format("executing '%1%'") % pager); - }); - - pid.setKillSignal(SIGINT); - - if (dup2(toPager.writeSide.get(), STDOUT_FILENO) == -1) { - throw SysError("dupping stdout"); - } -} - -RunPager::~RunPager() { - try { - if (pid != Pid(-1)) { - std::cout.flush(); - close(STDOUT_FILENO); - pid.wait(); - } - } catch (...) { - ignoreException(); - } -} - -std::string showBytes(unsigned long long bytes) { - return (format("%.2f MiB") % (bytes / (1024.0 * 1024.0))).str(); -} - -PrintFreed::~PrintFreed() { - if (show) { - std::cout << format("%1% store paths deleted, %2% freed\n") % - results.paths.size() % showBytes(results.bytesFreed); - } -} - -Exit::~Exit() = default; - -} // namespace nix diff --git a/third_party/nix/src/libmain/shared.hh b/third_party/nix/src/libmain/shared.hh deleted file mode 100644 index d1061d5e04e5..000000000000 --- a/third_party/nix/src/libmain/shared.hh +++ /dev/null @@ -1,134 +0,0 @@ -#pragma once - -#include <locale> - -#include <absl/strings/numbers.h> -#include <signal.h> - -#include "libmain/common-args.hh" -#include "libutil/args.hh" -#include "libutil/util.hh" - -namespace nix { - -class Exit : public std::exception { - public: - int status; - Exit() : status(0) {} - Exit(int status) : status(status) {} - virtual ~Exit(); -}; - -int handleExceptions(const std::string& programName, - const std::function<void()>& fun); - -void initNix(); - -void parseCmdLine( - int argc, char** argv, - std::function<bool(Strings::iterator& arg, const Strings::iterator& end)> - parseArg); - -void parseCmdLine( - const std::string& programName, const Strings& args, - std::function<bool(Strings::iterator& arg, const Strings::iterator& end)> - parseArg); - -void printVersion(const std::string& programName); - -/* Ugh. No better place to put this. */ -void printGCWarning(); - -class Store; - -void printMissing(const ref<Store>& store, const PathSet& paths); - -void printMissing(const ref<Store>& store, const PathSet& willBuild, - const PathSet& willSubstitute, const PathSet& unknown, - unsigned long long downloadSize, unsigned long long narSize); - -std::string getArg(const std::string& opt, Strings::iterator& i, - const Strings::iterator& end); - -template <class N> -N getIntArg(const std::string& opt, Strings::iterator& i, - const Strings::iterator& end, bool allowUnit) { - ++i; - if (i == end) { - throw UsageError(format("'%1%' requires an argument") % opt); - } - std::string s = *i; - N multiplier = 1; - if (allowUnit && !s.empty()) { - char u = std::toupper(*s.rbegin()); - if (std::isalpha(u)) { - if (u == 'K') { - multiplier = 1ULL << 10; - } else if (u == 'M') { - multiplier = 1ULL << 20; - } else if (u == 'G') { - multiplier = 1ULL << 30; - } else if (u == 'T') { - multiplier = 1ULL << 40; - } else { - throw UsageError(format("invalid unit specifier '%1%'") % u); - } - - s.resize(s.size() - 1); - } - } - N n; - if (!absl::SimpleAtoi(s, &n)) { - throw UsageError(format("'%1%' requires an integer argument") % opt); - } - return n * multiplier; -} - -struct LegacyArgs : public MixCommonArgs { - std::function<bool(Strings::iterator& arg, const Strings::iterator& end)> - parseArg; - - LegacyArgs( - const std::string& programName, - std::function<bool(Strings::iterator& arg, const Strings::iterator& end)> - parseArg); - - bool processFlag(Strings::iterator& pos, Strings::iterator end) override; - - bool processArgs(const Strings& args, bool finish) override; -}; - -/* Show the manual page for the specified program. */ -void showManPage(const std::string& name); - -/* The constructor of this class starts a pager if stdout is a - terminal and $PAGER is set. Stdout is redirected to the pager. */ -class RunPager { - public: - RunPager(); - ~RunPager(); - - private: - Pid pid; -}; - -extern volatile ::sig_atomic_t blockInt; - -/* GC helpers. */ - -std::string showBytes(unsigned long long bytes); - -struct GCResults; - -struct PrintFreed { - bool show; - const GCResults& results; - PrintFreed(bool show, const GCResults& results) - : show(show), results(results) {} - ~PrintFreed(); -}; - -/* Install a SIGSEGV handler to detect stack overflows. */ -void detectStackOverflow(); - -} // namespace nix diff --git a/third_party/nix/src/libmain/stack.cc b/third_party/nix/src/libmain/stack.cc deleted file mode 100644 index 628b6313a89c..000000000000 --- a/third_party/nix/src/libmain/stack.cc +++ /dev/null @@ -1,75 +0,0 @@ -#include <csignal> -#include <cstddef> -#include <cstdlib> -#include <cstring> - -#include <unistd.h> - -#include "libutil/types.hh" - -namespace nix { - -static void sigsegvHandler(int signo, siginfo_t* info, void* ctx) { - /* Detect stack overflows by comparing the faulting address with - the stack pointer. Unfortunately, getting the stack pointer is - not portable. */ - bool haveSP = true; - char* sp = nullptr; -#if defined(__x86_64__) && defined(REG_RSP) - sp = (char*)(static_cast<ucontext_t*>(ctx))->uc_mcontext.gregs[REG_RSP]; -#elif defined(REG_ESP) - sp = (char*)((ucontext_t*)ctx)->uc_mcontext.gregs[REG_ESP]; -#else - haveSP = false; -#endif - - if (haveSP) { - ptrdiff_t diff = static_cast<char*>(info->si_addr) - sp; - if (diff < 0) { - diff = -diff; - } - if (diff < 4096) { - char msg[] = "error: stack overflow (possible infinite recursion)\n"; - [[gnu::unused]] auto res = write(2, msg, strlen(msg)); - _exit(1); // maybe abort instead? - } - } - - /* Restore default behaviour (i.e. segfault and dump core). */ - struct sigaction act; - sigfillset(&act.sa_mask); - act.sa_handler = SIG_DFL; - act.sa_flags = 0; - if (sigaction(SIGSEGV, &act, nullptr) != 0) { - abort(); - } -} - -void detectStackOverflow() { -#if defined(SA_SIGINFO) && defined(SA_ONSTACK) - /* Install a SIGSEGV handler to detect stack overflows. This - requires an alternative stack, otherwise the signal cannot be - delivered when we're out of stack space. */ - stack_t stack; - stack.ss_size = 4096 * 4 + MINSIGSTKSZ; - static auto stackBuf = std::make_unique<std::vector<char>>(stack.ss_size); - stack.ss_sp = stackBuf->data(); - if (stack.ss_sp == nullptr) { - throw Error("cannot allocate alternative stack"); - } - stack.ss_flags = 0; - if (sigaltstack(&stack, nullptr) == -1) { - throw SysError("cannot set alternative stack"); - } - - struct sigaction act; - sigfillset(&act.sa_mask); - act.sa_sigaction = sigsegvHandler; - act.sa_flags = SA_SIGINFO | SA_ONSTACK; - if (sigaction(SIGSEGV, &act, nullptr) != 0) { - throw SysError("resetting SIGSEGV"); - } -#endif -} - -} // namespace nix |