From c8a0b9d5cbfe6619f8b38118f5b1d1875d1c5309 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 12 Feb 2019 13:43:32 +0100 Subject: experimental/optional -> optional --- src/libutil/util.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index bda87bee4..9f239bff3 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #ifndef HAVE_STRUCT_DIRENT_D_TYPE @@ -259,14 +259,14 @@ pid_t startProcess(std::function fun, const ProcessOptions & options = P shell backtick operator). */ string runProgram(Path program, bool searchPath = false, const Strings & args = Strings(), - const std::experimental::optional & input = {}); + const std::optional & input = {}); struct RunOptions { Path program; bool searchPath = true; Strings args; - std::experimental::optional input; + std::optional input; Source * standardIn = nullptr; Sink * standardOut = nullptr; bool _killStderr = false; -- cgit v1.2.3 From 7dcf5b011a0942ecf953f2b607c4c8d0e9e652c7 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 2 May 2019 21:09:52 +0200 Subject: Add function for quoting strings --- src/libutil/util.hh | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 9f239bff3..8bd57d2e4 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -334,8 +334,26 @@ template C tokenizeString(const string & s, const string & separators = /* Concatenate the given strings with a separator between the elements. */ -string concatStringsSep(const string & sep, const Strings & ss); -string concatStringsSep(const string & sep, const StringSet & ss); +template +string concatStringsSep(const string & sep, const C & ss) +{ + string s; + for (auto & i : ss) { + if (s.size() != 0) s += sep; + s += i; + } + return s; +} + + +/* Add quotes around a collection of strings. */ +template Strings quoteStrings(const C & c) +{ + Strings res; + for (auto & s : c) + res.push_back("'" + s + "'"); + return res; +} /* Remove trailing whitespace from a string. */ -- cgit v1.2.3 From 8ec77614f63e14d1869734b0d21a646667bbf88b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 2 May 2019 21:28:41 +0200 Subject: Move createTempFile to libutil --- src/libutil/util.hh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 8bd57d2e4..6c9d7c2eb 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -118,10 +118,6 @@ void deletePath(const Path & path); void deletePath(const Path & path, unsigned long long & bytesFreed); -/* Create a temporary directory. */ -Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix", - bool includePid = true, bool useGlobalCounter = true, mode_t mode = 0755); - /* Return $HOME or the user's home directory from /etc/passwd. */ Path getHome(); @@ -199,6 +195,14 @@ public: }; +/* Create a temporary directory. */ +Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix", + bool includePid = true, bool useGlobalCounter = true, mode_t mode = 0755); + +/* Create a temporary file, returning a file handle and its path. */ +std::pair createTempFile(const Path & prefix = "nix"); + + class Pipe { public: -- cgit v1.2.3 From ae7b56cd9a5ed8810828736fbb930a7c14ea44ca Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 May 2019 22:35:41 +0200 Subject: Get last commit time of github flakes --- src/libutil/util.hh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 35f9169f6..e05ef1e7d 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -142,10 +142,12 @@ Path getDataDir(); Paths createDirs(const Path & path); /* Create a symlink. */ -void createSymlink(const Path & target, const Path & link); +void createSymlink(const Path & target, const Path & link, + std::optional mtime = {}); /* Atomically create or replace a symlink. */ -void replaceSymlink(const Path & target, const Path & link); +void replaceSymlink(const Path & target, const Path & link, + std::optional mtime = {}); /* Wrappers arount read()/write() that read/write exactly the -- cgit v1.2.3 From 90df25ef7eb5157868a744906eaf6401430bb93d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 10 Oct 2019 15:07:50 +0200 Subject: Fix build --- src/libutil/util.hh | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 9f8c7092d..814028442 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -122,10 +122,6 @@ void deletePath(const Path & path); void deletePath(const Path & path, unsigned long long & bytesFreed); -/* Create a temporary directory. */ -Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix", - bool includePid = true, bool useGlobalCounter = true, mode_t mode = 0755); - std::string getUserName(); /* Return $HOME or the user's home directory from /etc/passwd. */ -- cgit v1.2.3 From 1bf9eb21b75f0d93d9c1633ea2e6fdf840047e79 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 8 Jan 2020 15:34:06 +0100 Subject: absPath(): Use std::optional --- src/libutil/util.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 5026db7cc..02c505cbc 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -46,7 +46,7 @@ void clearEnv(); /* Return an absolutized path, resolving paths relative to the specified directory, or the current directory otherwise. The path is also canonicalised. */ -Path absPath(Path path, Path dir = ""); +Path absPath(Path path, std::optional dir = {}); /* Canonicalise a path by removing all `.' or `..' components and double or trailing slashes. Optionally resolves all symlink -- cgit v1.2.3 From 9f4d8c6170517c9452e25dc29c56a6fbb43d40a1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 21 Jan 2020 16:27:53 +0100 Subject: Pluggable fetchers Flakes are now fetched using an extensible mechanism. Also lots of other flake cleanups. --- src/libutil/util.hh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 02c505cbc..2f1613ac1 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -46,7 +46,9 @@ void clearEnv(); /* Return an absolutized path, resolving paths relative to the specified directory, or the current directory otherwise. The path is also canonicalised. */ -Path absPath(Path path, std::optional dir = {}); +Path absPath(Path path, + std::optional dir = {}, + bool resolveSymlinks = false); /* Canonicalise a path by removing all `.' or `..' components and double or trailing slashes. Optionally resolves all symlink -- cgit v1.2.3 From 678301072f05b650dc15c5edb4c25f08f0d6cace Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 31 Jan 2020 14:01:46 +0100 Subject: nix flake list-inputs: Pretty-print the tree --- src/libutil/util.hh | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 2f1613ac1..5d44b92c3 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -458,6 +458,13 @@ void ignoreException(); #define ANSI_BLUE "\e[34;1m" +/* Tree formatting. */ +constexpr char treeConn[] = "╠═══"; +constexpr char treeLast[] = "╚═══"; +constexpr char treeLine[] = "║ "; +constexpr char treeNull[] = " "; + + /* Truncate a string to 'width' printable characters. If 'filterAll' is true, all ANSI escape sequences are filtered out. Otherwise, some escape sequences (such as colour setting) are copied but not @@ -583,4 +590,31 @@ extern PathFilter defaultPathFilter; AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode); +// A Rust/Python-like enumerate() iterator adapter. +// Borrowed from http://reedbeta.com/blog/python-like-enumerate-in-cpp17. +template ())), + typename = decltype(std::end(std::declval()))> +constexpr auto enumerate(T && iterable) +{ + struct iterator + { + size_t i; + TIter iter; + bool operator != (const iterator & other) const { return iter != other.iter; } + void operator ++ () { ++i; ++iter; } + auto operator * () const { return std::tie(i, *iter); } + }; + + struct iterable_wrapper + { + T iterable; + auto begin() { return iterator{ 0, std::begin(iterable) }; } + auto end() { return iterator{ 0, std::end(iterable) }; } + }; + + return iterable_wrapper{ std::forward(iterable) }; +} + + } -- cgit v1.2.3 From e91f32f2b58eda31fa8d8206ce9d0a8aef52ad13 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 31 Jan 2020 14:06:26 +0100 Subject: Use light box drawing symbols --- src/libutil/util.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 5d44b92c3..320590836 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -459,9 +459,9 @@ void ignoreException(); /* Tree formatting. */ -constexpr char treeConn[] = "╠═══"; -constexpr char treeLast[] = "╚═══"; -constexpr char treeLine[] = "║ "; +constexpr char treeConn[] = "├───"; +constexpr char treeLast[] = "└───"; +constexpr char treeLine[] = "│ "; constexpr char treeNull[] = " "; -- cgit v1.2.3 From 8414685c0f0c0d744c70d438894e4ecd7a078808 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 31 Jan 2020 19:16:40 +0100 Subject: Change lock file format to use an attribute representation of flake refs rather than URLs --- src/libutil/util.hh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 320590836..0aee67008 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -483,10 +483,11 @@ string base64Decode(const string & s); /* Get a value for the specified key from an associate container, or a default value if the key doesn't exist. */ template -std::optional get(const T & map, const std::string & key) +std::optional get(const T & map, const typename T::key_type & key) { auto i = map.find(key); - return i == map.end() ? std::optional() : i->second; + if (i == map.end()) return {}; + return std::optional(i->second); } -- cgit v1.2.3 From 8451298b35353abafe385124cb55e8d4911032ad Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sat, 1 Feb 2020 16:41:54 +0100 Subject: Factor out TreeInfo --- src/libutil/util.hh | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 0aee67008..9a6268346 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -455,6 +455,7 @@ void ignoreException(); #define ANSI_FAINT "\e[2m" #define ANSI_RED "\e[31;1m" #define ANSI_GREEN "\e[32;1m" +#define ANSI_YELLOW "\e[33;1m" #define ANSI_BLUE "\e[34;1m" -- cgit v1.2.3 From 0884f180f5ca8a864e6db5256eaa10646e87d671 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 10 May 2020 21:50:32 +0200 Subject: Simplify --- src/libutil/util.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 4be1d4580..a861d5aa6 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -431,7 +431,7 @@ template bool string2Float(const string & s, N & n) /* Return true iff `s' starts with `prefix'. */ -bool hasPrefix(const string & s, const string & prefix); +bool hasPrefix(std::string_view s, std::string_view prefix); /* Return true iff `s' ends in `suffix'. */ -- cgit v1.2.3 From ffc18583b1a086849ac0efd17da40ff510299b52 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sun, 12 Jul 2020 22:15:14 +0000 Subject: Move C++17 "pattern matching" boilerplat to utils.hh --- src/libutil/util.hh | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 3641daaec..d38657843 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -597,4 +597,9 @@ constexpr auto enumerate(T && iterable) } +// C++17 std::visit boilerplate +template struct overloaded : Ts... { using Ts::operator()...; }; +template overloaded(Ts...) -> overloaded; + + } -- cgit v1.2.3 From 3f6e88a5527dcc4d58e3147f78388a88eb8896e0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 30 Jul 2020 13:10:49 +0200 Subject: unsigned long long -> uint64_t --- src/libutil/util.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 42130f6dc..6850b5a7a 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -125,7 +125,7 @@ void writeLine(int fd, string s); second variant returns the number of bytes and blocks freed. */ void deletePath(const Path & path); -void deletePath(const Path & path, unsigned long long & bytesFreed); +void deletePath(const Path & path, uint64_t & bytesFreed); std::string getUserName(); -- cgit v1.2.3 From dc2f278c95ce4a73749cbb8221a568201535d46a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 20 Aug 2020 12:21:46 +0200 Subject: Allow 'nix' subcommands to provide docs in Markdown format --- src/libutil/util.hh | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 3a20679a8..082e26375 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -464,6 +464,12 @@ string base64Encode(std::string_view s); string base64Decode(std::string_view s); +/* Remove common leading whitespace from the lines in the string + 's'. For example, if every line is indented by at least 3 spaces, + then we remove 3 spaces from the start of every line. */ +std::string stripIndentation(std::string_view s); + + /* Get a value for the specified key from an associate container. */ template std::optional get(const T & map, const typename T::key_type & key) -- cgit v1.2.3 From d51ba430473368b29abfd1a8c4655da74b3a780c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 21 Sep 2020 18:40:11 +0200 Subject: Move Callback into its own header This gets rid of the inclusion of in util.hh, cutting compilation time by ~20s (CPU time). Issue #4045. --- src/libutil/util.hh | 38 +------------------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 082e26375..91e0a1543 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -17,7 +17,6 @@ #include #include #include -#include #include #ifndef HAVE_STRUCT_DIRENT_D_TYPE @@ -480,43 +479,8 @@ std::optional get(const T & map, const typename T::key_ } -/* A callback is a wrapper around a lambda that accepts a valid of - type T or an exception. (We abuse std::future to pass the value or - exception.) */ template -class Callback -{ - std::function)> fun; - std::atomic_flag done = ATOMIC_FLAG_INIT; - -public: - - Callback(std::function)> fun) : fun(fun) { } - - Callback(Callback && callback) : fun(std::move(callback.fun)) - { - auto prev = callback.done.test_and_set(); - if (prev) done.test_and_set(); - } - - void operator()(T && t) noexcept - { - auto prev = done.test_and_set(); - assert(!prev); - std::promise promise; - promise.set_value(std::move(t)); - fun(promise.get_future()); - } - - void rethrow(const std::exception_ptr & exc = std::current_exception()) noexcept - { - auto prev = done.test_and_set(); - assert(!prev); - std::promise promise; - promise.set_exception(exc); - fun(promise.get_future()); - } -}; +class Callback; /* Start a thread that handles various signals. Also block those signals -- cgit v1.2.3 From 557d2427ee7c21b32e691e1c44f682b667673a70 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 21 Sep 2020 18:57:02 +0200 Subject: Random header cleanup --- src/libutil/util.hh | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 91e0a1543..b8e201203 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -12,12 +12,9 @@ #include #include -#include -#include #include #include #include -#include #ifndef HAVE_STRUCT_DIRENT_D_TYPE #define DT_UNKNOWN 0 -- cgit v1.2.3 From 6691256e790b2917ccd06f16472b667426d0f413 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 6 Oct 2020 10:40:49 +0200 Subject: Factor out common showBytes() --- src/libutil/util.hh | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index b8e201203..129d59a97 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -573,4 +573,7 @@ template struct overloaded : Ts... { using Ts::operator()...; }; template overloaded(Ts...) -> overloaded; +std::string showBytes(uint64_t bytes); + + } -- cgit v1.2.3 From aef44cbaa9aaa6fa40eb34c411cedd858e16101e Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sun, 11 Oct 2020 16:38:46 +0000 Subject: Split out `commonChildInit` --- src/libutil/util.hh | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 129d59a97..cafe93702 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -536,6 +536,8 @@ typedef std::function PathFilter; extern PathFilter defaultPathFilter; +/* Common initialisation performed in child processes. */ +void commonChildInit(Pipe & logPipe); /* Create a Unix domain socket in listen mode. */ AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode); -- cgit v1.2.3 From 88798613ee288c7a801dcc1e73723a10a385df38 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 10 Nov 2020 14:59:03 +0100 Subject: replaceStrings(): Use std::string_view --- src/libutil/util.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index cafe93702..117fe86e7 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -383,7 +383,7 @@ string trim(const string & s, const string & whitespace = " \n\r\t"); /* Replace all occurrences of a string inside another string. */ -string replaceStrings(const std::string & s, +string replaceStrings(std::string_view s, const std::string & from, const std::string & to); -- cgit v1.2.3 From aa684861127eabc18a0d7386a66c5b75d4962897 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 2 Dec 2020 12:43:52 +0100 Subject: writeFull/writeFile: Use std::string_view --- src/libutil/util.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 117fe86e7..eb872dd4b 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -106,7 +106,7 @@ string readFile(const Path & path); void readFile(const Path & path, Sink & sink); /* Write a string to a file. */ -void writeFile(const Path & path, const string & s, mode_t mode = 0666); +void writeFile(const Path & path, std::string_view s, mode_t mode = 0666); void writeFile(const Path & path, Source & source, mode_t mode = 0666); @@ -157,7 +157,7 @@ void replaceSymlink(const Path & target, const Path & link, requested number of bytes. */ void readFull(int fd, unsigned char * buf, size_t count); void writeFull(int fd, const unsigned char * buf, size_t count, bool allowInterrupts = true); -void writeFull(int fd, const string & s, bool allowInterrupts = true); +void writeFull(int fd, std::string_view s, bool allowInterrupts = true); MakeError(EndOfFile, Error); -- cgit v1.2.3 From faa31f40846f7a4dbc2487d000b112a6aef69d1b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 2 Dec 2020 14:00:43 +0100 Subject: Sink: Use std::string_view --- src/libutil/util.hh | 1 - 1 file changed, 1 deletion(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index eb872dd4b..fcb7cad39 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -156,7 +156,6 @@ void replaceSymlink(const Path & target, const Path & link, /* Wrappers arount read()/write() that read/write exactly the requested number of bytes. */ void readFull(int fd, unsigned char * buf, size_t count); -void writeFull(int fd, const unsigned char * buf, size_t count, bool allowInterrupts = true); void writeFull(int fd, std::string_view s, bool allowInterrupts = true); MakeError(EndOfFile, Error); -- cgit v1.2.3 From 1b79b5b983a6c775766bd0d1c7881042188998b8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 2 Dec 2020 14:10:56 +0100 Subject: read(): Use char * instead of unsigned char * This gets rid of some pointless casts. --- src/libutil/util.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index fcb7cad39..0f82bed78 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -155,7 +155,7 @@ void replaceSymlink(const Path & target, const Path & link, /* Wrappers arount read()/write() that read/write exactly the requested number of bytes. */ -void readFull(int fd, unsigned char * buf, size_t count); +void readFull(int fd, char * buf, size_t count); void writeFull(int fd, std::string_view s, bool allowInterrupts = true); MakeError(EndOfFile, Error); -- cgit v1.2.3 From 6548b89cc4eb214cb4632fd4332c610f2d1f0a9d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 8 Jan 2021 12:22:21 +0100 Subject: string2Int(): Return std::optional --- src/libutil/util.hh | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 0f82bed78..7a4d5fe92 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -397,21 +397,27 @@ bool statusOk(int status); /* Parse a string into an integer. */ -template bool string2Int(const string & s, N & n) +template +std::optional string2Int(const std::string & s) { - if (string(s, 0, 1) == "-" && !std::numeric_limits::is_signed) - return false; + if (s.substr(0, 1) == "-" && !std::numeric_limits::is_signed) + return {}; std::istringstream str(s); + N n; str >> n; - return str && str.get() == EOF; + if (str && str.get() == EOF) return n; + return {}; } /* Parse a string into a float. */ -template bool string2Float(const string & s, N & n) +template +std::optional string2Float(const string & s) { std::istringstream str(s); + N n; str >> n; - return str && str.get() == EOF; + if (str && str.get() == EOF) return n; + return {}; } -- cgit v1.2.3 From 17beae299d5e6bb511c453d0b9d0d7ef906b3d14 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 8 Jan 2021 12:51:19 +0100 Subject: Support binary unit prefixes in command line arguments --- src/libutil/util.hh | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 7a4d5fe92..ab0bd865a 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -401,12 +401,34 @@ template std::optional string2Int(const std::string & s) { if (s.substr(0, 1) == "-" && !std::numeric_limits::is_signed) - return {}; + return std::nullopt; std::istringstream str(s); N n; str >> n; if (str && str.get() == EOF) return n; - return {}; + return std::nullopt; +} + +/* Like string2Int(), but support an optional suffix 'K', 'M', 'G' or + 'T' denoting a binary unit prefix. */ +template +N string2IntWithUnitPrefix(std::string s) +{ + N multiplier = 1; + if (!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("invalid unit specifier '%1%'", u); + s.resize(s.size() - 1); + } + } + if (auto n = string2Int(s)) + return *n * multiplier; + throw UsageError("'%s' is not an integer", s); } /* Parse a string into a float. */ @@ -417,7 +439,7 @@ std::optional string2Float(const string & s) N n; str >> n; if (str && str.get() == EOF) return n; - return {}; + return std::nullopt; } -- cgit v1.2.3 From 40608342cb3772a6d2a6c125cc2237b97c028ab4 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 21 Jan 2021 00:49:29 +0100 Subject: Remove trailing whitespace --- src/libutil/util.hh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index ab0bd865a..ad49c65b3 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -373,8 +373,9 @@ template Strings quoteStrings(const C & c) } -/* Remove trailing whitespace from a string. */ -string chomp(const string & s); +/* Remove trailing whitespace from a string. FIXME: return + std::string_view. */ +string chomp(std::string_view s); /* Remove whitespace from the start and end of a string. */ -- cgit v1.2.3 From 8a29052cb2f52ef2c82c36fb3818fd0f66349729 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 7 Apr 2021 12:21:31 +0200 Subject: PathSubstitutionGoal: Clean up pipe If there were many top-level goals (which are not destroyed until the very end), commands like $ nix copy --to 'ssh://localhost?remote-store=/tmp/nix' \ /run/current-system --no-check-sigs --substitute-on-destination could fail with "Too many open files". So now we do some explicit cleanup from amDone(). It would be cleaner to separate goals from their temporary internal state, but that would be a bigger refactor. --- src/libutil/util.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index ad49c65b3..ef5e5012b 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -188,7 +188,6 @@ public: class AutoCloseFD { int fd; - void close(); public: AutoCloseFD(); AutoCloseFD(int fd); @@ -200,6 +199,7 @@ public: int get() const; explicit operator bool() const; int release(); + void close(); }; @@ -216,6 +216,7 @@ class Pipe public: AutoCloseFD readSide, writeSide; void create(); + void close(); }; -- cgit v1.2.3 From 9b9e703df41d75949272059f9b8bc8b763e91fce Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 7 Apr 2021 13:10:02 +0200 Subject: restoreSignals() + restoreAffinity() -> restoreProcessContext() --- src/libutil/util.hh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index ef5e5012b..4762d1e55 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -300,6 +300,11 @@ std::pair runProgram(const RunOptions & options); void runProgram2(const RunOptions & options); +/* Restore the original inherited Unix process context (such as signal + masks, stack size, CPU affinity). */ +void restoreProcessContext(); + + class ExecError : public Error { public: @@ -513,9 +518,6 @@ class Callback; on the current thread (and thus any threads created by it). */ void startSignalHandlerThread(); -/* Restore default signal handling. */ -void restoreSignals(); - struct InterruptCallback { virtual ~InterruptCallback() { }; -- cgit v1.2.3 From 906adadacd2d1c98346a2f42c0b42a32d2806d94 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 7 Apr 2021 13:40:13 +0200 Subject: Restore stack size in child processes Fixes #4673. --- src/libutil/util.hh | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 4762d1e55..f84d0fb31 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -300,6 +300,10 @@ std::pair runProgram(const RunOptions & options); void runProgram2(const RunOptions & options); +/* Change the stack size. */ +void setStackSize(size_t stackSize); + + /* Restore the original inherited Unix process context (such as signal masks, stack size, CPU affinity). */ void restoreProcessContext(); -- cgit v1.2.3 From 20cce079f258dc3f62340ecd7b9de1bbd99ef814 Mon Sep 17 00:00:00 2001 From: "Yestin L. Harrison" Date: Thu, 1 Jul 2021 18:19:01 -0600 Subject: Respect TERM=dumb more consistently --- src/libutil/util.hh | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index f84d0fb31..a8dd4bd47 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -482,6 +482,9 @@ constexpr char treeLast[] = "└───"; constexpr char treeLine[] = "│ "; constexpr char treeNull[] = " "; +/* Determine whether ANSI escape sequences are appropriate for the + present output. */ +bool shouldANSI(); /* Truncate a string to 'width' printable characters. If 'filterAll' is true, all ANSI escape sequences are filtered out. Otherwise, -- cgit v1.2.3 From 4ed66735b67b785efad7e23599a1777343c264b5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 13 Sep 2021 23:22:09 +0200 Subject: RunOptions: Use designated initializers Also get rid of _killStderr because it wasn't actually checked anywhere. --- src/libutil/util.hh | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'src/libutil/util.hh') diff --git a/src/libutil/util.hh b/src/libutil/util.hh index a8dd4bd47..bee77b53f 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -276,26 +276,20 @@ string runProgram(Path program, bool searchPath = false, struct RunOptions { + Path program; + bool searchPath = true; + Strings args; std::optional uid; std::optional gid; std::optional chdir; std::optional> environment; - Path program; - bool searchPath = true; - Strings args; std::optional input; Source * standardIn = nullptr; Sink * standardOut = nullptr; bool mergeStderrToStdout = false; - bool _killStderr = false; - - RunOptions(const Path & program, const Strings & args) - : program(program), args(args) { }; - - RunOptions & killStderr(bool v) { _killStderr = true; return *this; } }; -std::pair runProgram(const RunOptions & options); +std::pair runProgram(RunOptions && options); void runProgram2(const RunOptions & options); -- cgit v1.2.3