1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-22 02:09:36 +01:00

Merge commit 'b24757f08a' into sync-2.24.2

This commit is contained in:
Eelco Dolstra 2024-08-08 15:34:12 +02:00
commit c1d27763c6
330 changed files with 4907 additions and 1814 deletions

View file

@ -29,6 +29,7 @@ struct Completions final : AddCompletions
*/
class RootArgs : virtual public Args
{
protected:
/**
* @brief The command's "working directory", but only set when top level.
*

View file

@ -6,6 +6,8 @@
#include <vector>
#include <limits>
#include "error.hh"
namespace nix {
/**
@ -30,7 +32,7 @@ private:
auto & addChunk()
{
if (size_ >= std::numeric_limits<uint32_t>::max() - ChunkSize)
abort();
unreachable();
chunks.emplace_back();
chunks.back().reserve(ChunkSize);
return chunks.back();

View file

@ -81,6 +81,7 @@ void BaseSetting<T>::convertToArg(Args & args, const std::string & category)
{
args.addFlag({
.longName = name,
.aliases = aliases,
.description = fmt("Set the `%s` setting.", name),
.category = category,
.labels = {"value"},
@ -91,6 +92,7 @@ void BaseSetting<T>::convertToArg(Args & args, const std::string & category)
if (isAppendable())
args.addFlag({
.longName = "extra-" + name,
.aliases = aliases,
.description = fmt("Append to the `%s` setting.", name),
.category = category,
.labels = {"value"},

View file

@ -1,6 +1,7 @@
#include "config.hh"
#include "args.hh"
#include "abstract-setting-to-json.hh"
#include "environment-variables.hh"
#include "experimental-features.hh"
#include "util.hh"
#include "file-system.hh"
@ -170,9 +171,18 @@ void AbstractConfig::applyConfig(const std::string & contents, const std::string
set(name, value);
// Then apply other settings
for (const auto & [name, value] : parsedContents)
if (name != "experimental-features" && name != "extra-experimental-features")
// XXX: NIX_PATH must override the regular setting! This is done in `initGC()`
// Environment variables overriding settings should probably be part of the Config mechanism,
// but at the time of writing it's not worth building that for just one thing
for (const auto & [name, value] : parsedContents) {
if (name != "experimental-features" && name != "extra-experimental-features") {
if ((name == "nix-path" || name == "extra-nix-path")
&& getEnv("NIX_PATH").has_value()) {
continue;
}
set(name, value);
}
}
}
void Config::resetOverridden()
@ -292,6 +302,7 @@ template<> void BaseSetting<bool>::convertToArg(Args & args, const std::string &
{
args.addFlag({
.longName = name,
.aliases = aliases,
.description = fmt("Enable the `%s` setting.", name),
.category = category,
.handler = {[this] { override(true); }},
@ -299,6 +310,7 @@ template<> void BaseSetting<bool>::convertToArg(Args & args, const std::string &
});
args.addFlag({
.longName = "no-" + name,
.aliases = aliases,
.description = fmt("Disable the `%s` setting.", name),
.category = category,
.handler = {[this] { override(false); }},

View file

@ -393,7 +393,7 @@ struct ExperimentalFeatureSettings : Config {
{{#include experimental-features-shortlist.md}}
Experimental features are [further documented in the manual](@docroot@/contributing/experimental-features.md).
Experimental features are [further documented in the manual](@docroot@/development/experimental-features.md).
)"};
/**

View file

@ -15,13 +15,12 @@
#if __linux__
# include <mutex>
# include <sys/resource.h>
# include "cgroup.hh"
# include "namespaces.hh"
#endif
#ifndef _WIN32
# include <sys/mount.h>
# include <sys/resource.h>
#endif
namespace nix {
@ -138,7 +137,7 @@ std::optional<Path> getSelfExe()
{
static auto cached = []() -> std::optional<Path>
{
#if __linux__
#if __linux__ || __GNU__
return readLink("/proc/self/exe");
#elif __APPLE__
char buf[1024];

View file

@ -1,3 +1,5 @@
#include <algorithm>
#include "error.hh"
#include "environment-variables.hh"
#include "signals.hh"
@ -430,4 +432,36 @@ std::ostream & showErrorInfo(std::ostream & out, const ErrorInfo & einfo, bool s
return out;
}
/** Write to stderr in a robust and minimal way, considering that the process
* may be in a bad state.
*/
static void writeErr(std::string_view buf)
{
while (!buf.empty()) {
auto n = write(STDERR_FILENO, buf.data(), buf.size());
if (n < 0) {
if (errno == EINTR) continue;
abort();
}
buf = buf.substr(n);
}
}
void panic(std::string_view msg)
{
writeErr("\n\n" ANSI_RED "terminating due to unexpected unrecoverable internal error: " ANSI_NORMAL );
writeErr(msg);
writeErr("\n");
abort();
}
void panic(const char * file, int line, const char * func)
{
char buf[512];
int n = snprintf(buf, sizeof(buf), "Unexpected condition in %s at %s:%d", func, file, line);
if (n < 0)
panic("Unexpected condition and could not format error message");
panic(std::string_view(buf, std::min(static_cast<int>(sizeof(buf)), n)));
}
}

View file

@ -273,4 +273,24 @@ using NativeSysError =
*/
void throwExceptionSelfCheck();
/**
* Print a message and abort().
*/
[[noreturn]]
void panic(std::string_view msg);
/**
* Print a basic error message with source position and abort().
* Use the unreachable() macro to call this.
*/
[[noreturn]]
void panic(const char * file, int line, const char * func);
/**
* Print a basic error message with source position and abort().
*
* @note: This assumes that the logger is operational
*/
#define unreachable() (::nix::panic(__FILE__, __LINE__, __func__))
}

View file

@ -24,7 +24,7 @@ struct ExperimentalFeatureDetails
* feature, we either have no issue at all if few features are not added
* at the end of the list, or a proper merge conflict if they are.
*/
constexpr size_t numXpFeatures = 1 + static_cast<size_t>(Xp::VerifiedFetches);
constexpr size_t numXpFeatures = 1 + static_cast<size_t>(Xp::PipeOperators);
constexpr std::array<ExperimentalFeatureDetails, numXpFeatures> xpFeatureDetails = {{
{
@ -287,6 +287,14 @@ constexpr std::array<ExperimentalFeatureDetails, numXpFeatures> xpFeatureDetails
)",
.trackingUrl = "https://github.com/NixOS/nix/milestone/48",
},
{
.tag = Xp::PipeOperators,
.name = "pipe-operators",
.description = R"(
Add `|>` and `<|` operators to the Nix language.
)",
.trackingUrl = "https://github.com/NixOS/nix/milestone/55",
},
}};
static_assert(

View file

@ -34,6 +34,7 @@ enum struct ExperimentalFeature
ConfigurableImpureEnv,
MountedSSHStore,
VerifiedFetches,
PipeOperators,
};
extern std::set<std::string> stabilizedFeatures;

View file

@ -63,7 +63,7 @@ std::string_view renderFileIngestionMethod(FileIngestionMethod method)
case FileIngestionMethod::Git:
return "git";
default:
abort();
unreachable();
}
}

View file

@ -416,7 +416,11 @@ void deletePath(const fs::path & path)
void createDir(const Path & path, mode_t mode)
{
if (mkdir(path.c_str(), mode) == -1)
if (mkdir(path.c_str()
#ifndef _WIN32
, mode
#endif
) == -1)
throw SysError("creating directory '%1%'", path);
}

View file

@ -53,7 +53,7 @@ void copyRecursive(
throw Error("file '%1%' has an unsupported type", from);
default:
abort();
unreachable();
}
}
@ -97,7 +97,7 @@ void RestoreSink::createRegularFile(const CanonPath & path, std::function<void(C
RestoreRegularFile crf;
crf.fd =
#ifdef _WIN32
CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)
CreateFileW(p.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)
#else
open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, 0666)
#endif
@ -145,7 +145,7 @@ void RestoreRegularFile::operator () (std::string_view data)
void RestoreSink::createSymlink(const CanonPath & path, const std::string & target)
{
auto p = append(dstPath, path);
nix::createSymlink(target, p);
nix::createSymlink(target, p.string());
}

View file

@ -201,7 +201,7 @@ std::optional<Mode> convertMode(SourceAccessor::Type type)
case SourceAccessor::tRegular: return Mode::Regular;
case SourceAccessor::tDirectory: return Mode::Directory;
case SourceAccessor::tMisc: return std::nullopt;
default: abort();
default: unreachable();
}
}

View file

@ -25,7 +25,7 @@ static size_t regularHashSize(HashAlgorithm type) {
case HashAlgorithm::SHA256: return sha256HashSize;
case HashAlgorithm::SHA512: return sha512HashSize;
}
abort();
unreachable();
}

View file

@ -189,7 +189,7 @@ struct JSONLogger : Logger {
else if (f.type == Logger::Field::tString)
arr.push_back(f.s);
else
abort();
unreachable();
}
void write(const nlohmann::json & json)

View file

@ -89,7 +89,7 @@ public:
return i->second.second;
}
size_t size()
size_t size() const
{
return data.size();
}

View file

@ -62,6 +62,7 @@ endif
boost = dependency(
'boost',
modules : ['context', 'coroutine'],
include_type: 'system',
)
# boost is a public dependency, but not a pkg-config dependency unfortunately, so we
# put in `deps_other`.
@ -216,6 +217,7 @@ headers = [config_h] + files(
'source-accessor.hh',
'source-path.hh',
'split.hh',
'std-hash.hh',
'strings.hh',
'strings-inline.hh',
'suggestions.hh',

View file

@ -88,12 +88,8 @@ mkMesonDerivation (finalAttrs: {
LDFLAGS = "-fuse-ld=gold";
};
enableParallelBuilding = true;
separateDebugInfo = !stdenv.hostPlatform.isStatic;
strictDeps = true;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
meta = {

View file

@ -119,12 +119,12 @@ std::optional<std::string> Pos::getSnippetUpTo(const Pos & end) const {
if (auto source = getSource()) {
auto firstLine = LinesIterator(*source);
for (auto i = 1; i < this->line; ++i) {
for (uint32_t i = 1; i < this->line; ++i) {
++firstLine;
}
auto lastLine = LinesIterator(*source);
for (auto i = 1; i < end.line; ++i) {
for (uint32_t i = 1; i < end.line; ++i) {
++lastLine;
}

View file

@ -97,7 +97,7 @@ std::optional<struct stat> PosixSourceAccessor::cachedLstat(const CanonPath & pa
Path absPath = makeAbsPath(path).string();
{
auto cache(_cache.read());
auto cache(_cache.readLock());
auto i = cache->find(absPath);
if (i != cache->end()) return i->second;
}

View file

@ -23,14 +23,14 @@ public:
: p(r.p)
{ }
explicit ref<T>(const std::shared_ptr<T> & p)
explicit ref(const std::shared_ptr<T> & p)
: p(p)
{
if (!p)
throw std::invalid_argument("null pointer cast to ref");
}
explicit ref<T>(T * p)
explicit ref(T * p)
: p(p)
{
if (!p)

View file

@ -190,11 +190,11 @@ struct VirtualStackAllocator {
class DefaultStackAllocator : public StackAllocator {
boost::coroutines2::default_stack stack;
boost::context::stack_context allocate() {
boost::context::stack_context allocate() override {
return stack.allocate();
}
void deallocate(boost::context::stack_context sctx) {
void deallocate(boost::context::stack_context sctx) override {
stack.deallocate(sctx);
}
};
@ -260,7 +260,7 @@ std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun)
});
}
if (!*coro) { abort(); }
if (!*coro) { unreachable(); }
if (!cur.empty()) {
CoroutineContext ctx;
@ -271,12 +271,12 @@ std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun)
void finish() override
{
if (!coro) return;
if (!*coro) abort();
if (!*coro) unreachable();
{
CoroutineContext ctx;
(*coro)(true);
}
if (*coro) abort();
if (*coro) unreachable();
}
};
@ -316,7 +316,7 @@ std::unique_ptr<Source> sinkToSource(
});
}
if (!*coro) { eof(); abort(); }
if (!*coro) { eof(); unreachable(); }
if (pos == cur.size()) {
if (!cur.empty()) {

View file

@ -159,13 +159,7 @@ struct FdSource : BufferedSource
FdSource(Descriptor fd) : fd(fd) { }
FdSource(FdSource &&) = default;
FdSource & operator=(FdSource && s)
{
fd = s.fd;
s.fd = INVALID_DESCRIPTOR;
read = s.read;
return *this;
}
FdSource & operator=(FdSource && s) = default;
bool good() override;
protected:
@ -210,7 +204,7 @@ struct TeeSink : Sink
{
Sink & sink1, & sink2;
TeeSink(Sink & sink1, Sink & sink2) : sink1(sink1), sink2(sink2) { }
virtual void operator () (std::string_view data)
virtual void operator () (std::string_view data) override
{
sink1(data);
sink2(data);
@ -227,7 +221,7 @@ struct TeeSource : Source
Sink & sink;
TeeSource(Source & orig, Sink & sink)
: orig(orig), sink(sink) { }
size_t read(char * data, size_t len)
size_t read(char * data, size_t len) override
{
size_t n = orig.read(data, len);
sink({data, n});
@ -244,7 +238,7 @@ struct SizedSource : Source
size_t remain;
SizedSource(Source & orig, size_t size)
: orig(orig), remain(size) { }
size_t read(char * data, size_t len)
size_t read(char * data, size_t len) override
{
if (this->remain <= 0) {
throw EndOfFile("sized: unexpected end-of-file");
@ -489,13 +483,17 @@ struct FramedSource : Source
~FramedSource()
{
if (!eof) {
while (true) {
auto n = readInt(from);
if (!n) break;
std::vector<char> data(n);
from(data.data(), n);
try {
if (!eof) {
while (true) {
auto n = readInt(from);
if (!n) break;
std::vector<char> data(n);
from(data.data(), n);
}
}
} catch (...) {
ignoreException();
}
}

View file

@ -8,8 +8,7 @@
#include "ref.hh"
#include "canon-path.hh"
#include "source-accessor.hh"
#include <boost/functional/hash.hpp> // for boost::hash_combine
#include "std-hash.hh"
namespace nix {

24
src/libutil/std-hash.hh Normal file
View file

@ -0,0 +1,24 @@
#pragma once
//!@file Hashing utilities for use with unordered_map, etc. (ie low level implementation logic, not domain logic like
//! Nix hashing)
#include <functional>
namespace nix {
/**
* hash_combine() from Boost. Hash several hashable values together
* into a single hash.
*/
inline void hash_combine(std::size_t & seed) {}
template<typename T, typename... Rest>
inline void hash_combine(std::size_t & seed, const T & v, Rest... rest)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
hash_combine(seed, rest...);
}
} // namespace nix

View file

@ -7,6 +7,8 @@
#include <condition_variable>
#include <cassert>
#include "error.hh"
namespace nix {
/**
@ -47,7 +49,7 @@ public:
friend SyncBase;
Lock(SyncBase * s) : s(s), lk(s->mutex) { }
public:
Lock(Lock && l) : s(l.s) { abort(); }
Lock(Lock && l) : s(l.s) { unreachable(); }
Lock(const Lock & l) = delete;
~Lock() { }
@ -104,7 +106,7 @@ public:
* Acquire read access to the inner value. When using
* `std::shared_mutex`, this will use a shared lock.
*/
ReadLock read() const { return ReadLock(const_cast<SyncBase *>(this)); }
ReadLock readLock() const { return ReadLock(const_cast<SyncBase *>(this)); }
};
template<class T>

View file

@ -40,7 +40,9 @@ public:
#endif
;
auto count = poll(fds, 1, -1);
if (count == -1) abort(); // can't happen
if (count == -1)
unreachable();
/* This shouldn't happen, but can on macOS due to a bug.
See rdar://37550628.

View file

@ -182,7 +182,7 @@ static pid_t doFork(bool allowVfork, ChildWrapperFunction & fun)
#endif
if (pid != 0) return pid;
fun();
abort();
unreachable();
}

View file

@ -375,18 +375,4 @@ inline std::string operator + (std::string_view s1, const char * s2)
return s;
}
/**
* hash_combine() from Boost. Hash several hashable values together
* into a single hash.
*/
inline void hash_combine(std::size_t & seed) { }
template <typename T, typename... Rest>
inline void hash_combine(std::size_t & seed, const T & v, Rest... rest)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
hash_combine(seed, rest...);
}
}