1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 10:41:16 +02:00

Merge pull request #13123 from Mic92/filesystem-refactoring

Drop fs alias in favour of std::filesystem
This commit is contained in:
Eelco Dolstra 2025-05-02 12:52:12 +02:00 committed by GitHub
commit a976a46ee8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 138 additions and 198 deletions

View file

@ -18,7 +18,6 @@
namespace nix { namespace nix {
namespace fs { using namespace std::filesystem; }
fetchers::Settings fetchSettings; fetchers::Settings fetchSettings;
@ -123,8 +122,8 @@ MixEvalArgs::MixEvalArgs()
.category = category, .category = category,
.labels = {"original-ref", "resolved-ref"}, .labels = {"original-ref", "resolved-ref"},
.handler = {[&](std::string _from, std::string _to) { .handler = {[&](std::string _from, std::string _to) {
auto from = parseFlakeRef(fetchSettings, _from, fs::current_path().string()); auto from = parseFlakeRef(fetchSettings, _from, std::filesystem::current_path().string());
auto to = parseFlakeRef(fetchSettings, _to, fs::current_path().string()); auto to = parseFlakeRef(fetchSettings, _to, std::filesystem::current_path().string());
fetchers::Attrs extraAttrs; fetchers::Attrs extraAttrs;
if (to.subdir != "") extraAttrs["dir"] = to.subdir; if (to.subdir != "") extraAttrs["dir"] = to.subdir;
fetchers::overrideRegistry(from.input, to.input, extraAttrs); fetchers::overrideRegistry(from.input, to.input, extraAttrs);

View file

@ -31,8 +31,6 @@
namespace nix { namespace nix {
namespace fs { using namespace std::filesystem; }
void completeFlakeInputAttrPath( void completeFlakeInputAttrPath(
AddCompletions & completions, AddCompletions & completions,
ref<EvalState> evalState, ref<EvalState> evalState,
@ -343,7 +341,7 @@ void completeFlakeRefWithFragment(
auto flakeRefS = std::string(prefix.substr(0, hash)); auto flakeRefS = std::string(prefix.substr(0, hash));
// TODO: ideally this would use the command base directory instead of assuming ".". // TODO: ideally this would use the command base directory instead of assuming ".".
auto flakeRef = parseFlakeRef(fetchSettings, expandTilde(flakeRefS), fs::current_path().string()); auto flakeRef = parseFlakeRef(fetchSettings, expandTilde(flakeRefS), std::filesystem::current_path().string());
auto evalCache = openEvalCache(*evalState, auto evalCache = openEvalCache(*evalState,
std::make_shared<flake::LockedFlake>(lockFlake( std::make_shared<flake::LockedFlake>(lockFlake(

View file

@ -11,14 +11,10 @@
namespace nix { namespace nix {
namespace fs {
using namespace std::filesystem;
}
class GitUtilsTest : public ::testing::Test class GitUtilsTest : public ::testing::Test
{ {
// We use a single repository for all tests. // We use a single repository for all tests.
fs::path tmpDir; std::filesystem::path tmpDir;
std::unique_ptr<AutoDelete> delTmpDir; std::unique_ptr<AutoDelete> delTmpDir;
public: public:

View file

@ -533,7 +533,7 @@ struct GitInputScheme : InputScheme
static MakeNotAllowedError makeNotAllowedError(std::filesystem::path repoPath) static MakeNotAllowedError makeNotAllowedError(std::filesystem::path repoPath)
{ {
return [repoPath{std::move(repoPath)}](const CanonPath & path) -> RestrictedPathError { return [repoPath{std::move(repoPath)}](const CanonPath & path) -> RestrictedPathError {
if (fs::symlink_exists(repoPath / path.rel())) if (pathExists(repoPath / path.rel()))
return RestrictedPathError( return RestrictedPathError(
"Path '%1%' in the repository %2% is not tracked by Git.\n" "Path '%1%' in the repository %2% is not tracked by Git.\n"
"\n" "\n"

View file

@ -811,7 +811,7 @@ LockedFlake lockFlake(
auto relPath = (topRef.subdir == "" ? "" : topRef.subdir + "/") + "flake.lock"; auto relPath = (topRef.subdir == "" ? "" : topRef.subdir + "/") + "flake.lock";
auto outputLockFilePath = *sourcePath / relPath; auto outputLockFilePath = *sourcePath / relPath;
bool lockFileExists = fs::symlink_exists(outputLockFilePath); bool lockFileExists = pathExists(outputLockFilePath);
auto s = chomp(diff); auto s = chomp(diff);
if (lockFileExists) { if (lockFileExists) {

View file

@ -11,8 +11,6 @@
#include <filesystem> #include <filesystem>
#include <gtest/gtest.h> #include <gtest/gtest.h>
namespace fs { using namespace std::filesystem; }
namespace nixC { namespace nixC {
class nix_api_store_test : public nix_api_util_context class nix_api_store_test : public nix_api_util_context
{ {
@ -27,10 +25,10 @@ public:
{ {
nix_store_free(store); nix_store_free(store);
for (auto & path : fs::recursive_directory_iterator(nixDir)) { for (auto & path : std::filesystem::recursive_directory_iterator(nixDir)) {
fs::permissions(path, fs::perms::owner_all); std::filesystem::permissions(path, std::filesystem::perms::owner_all);
} }
fs::remove_all(nixDir); std::filesystem::remove_all(nixDir);
} }
Store * store; Store * store;
@ -45,7 +43,7 @@ protected:
auto tmpl = nix::defaultTempDir() + "/tests_nix-store."; auto tmpl = nix::defaultTempDir() + "/tests_nix-store.";
for (size_t i = 0; true; ++i) { for (size_t i = 0; true; ++i) {
nixDir = tmpl + std::string { i }; nixDir = tmpl + std::string { i };
if (fs::create_directory(nixDir)) break; if (std::filesystem::create_directory(nixDir)) break;
} }
#else #else
// resolve any symlinks in i.e. on macOS /tmp -> /private/tmp // resolve any symlinks in i.e. on macOS /tmp -> /private/tmp

View file

@ -163,8 +163,8 @@ TEST(machines, getMachinesWithIncorrectFormat) {
} }
TEST(machines, getMachinesWithCorrectFileReference) { TEST(machines, getMachinesWithCorrectFileReference) {
auto path = fs::weakly_canonical(getUnitTestData() / "machines/valid"); auto path = std::filesystem::weakly_canonical(getUnitTestData() / "machines/valid");
ASSERT_TRUE(fs::exists(path)); ASSERT_TRUE(std::filesystem::exists(path));
auto actual = Machine::parseConfig({}, "@" + path.string()); auto actual = Machine::parseConfig({}, "@" + path.string());
ASSERT_THAT(actual, SizeIs(3)); ASSERT_THAT(actual, SizeIs(3));
@ -174,22 +174,22 @@ TEST(machines, getMachinesWithCorrectFileReference) {
} }
TEST(machines, getMachinesWithCorrectFileReferenceToEmptyFile) { TEST(machines, getMachinesWithCorrectFileReferenceToEmptyFile) {
fs::path path = "/dev/null"; std::filesystem::path path = "/dev/null";
ASSERT_TRUE(fs::exists(path)); ASSERT_TRUE(std::filesystem::exists(path));
auto actual = Machine::parseConfig({}, "@" + path.string()); auto actual = Machine::parseConfig({}, "@" + path.string());
ASSERT_THAT(actual, SizeIs(0)); ASSERT_THAT(actual, SizeIs(0));
} }
TEST(machines, getMachinesWithIncorrectFileReference) { TEST(machines, getMachinesWithIncorrectFileReference) {
auto path = fs::weakly_canonical("/not/a/file"); auto path = std::filesystem::weakly_canonical("/not/a/file");
ASSERT_TRUE(!fs::exists(path)); ASSERT_TRUE(!std::filesystem::exists(path));
auto actual = Machine::parseConfig({}, "@" + path.string()); auto actual = Machine::parseConfig({}, "@" + path.string());
ASSERT_THAT(actual, SizeIs(0)); ASSERT_THAT(actual, SizeIs(0));
} }
TEST(machines, getMachinesWithCorrectFileReferenceToIncorrectFile) { TEST(machines, getMachinesWithCorrectFileReferenceToIncorrectFile) {
EXPECT_THROW( EXPECT_THROW(
Machine::parseConfig({}, "@" + fs::weakly_canonical(getUnitTestData() / "machines" / "bad_format").string()), Machine::parseConfig({}, "@" + std::filesystem::weakly_canonical(getUnitTestData() / "machines" / "bad_format").string()),
FormatError); FormatError);
} }

View file

@ -3,8 +3,6 @@
namespace nix { namespace nix {
namespace fs { using namespace std::filesystem; }
void builtinUnpackChannel( void builtinUnpackChannel(
const BasicDerivation & drv, const BasicDerivation & drv,
const std::map<std::string, Path> & outputs) const std::map<std::string, Path> & outputs)
@ -15,11 +13,11 @@ void builtinUnpackChannel(
return i->second; return i->second;
}; };
fs::path out{outputs.at("out")}; std::filesystem::path out{outputs.at("out")};
auto & channelName = getAttr("channelName"); auto & channelName = getAttr("channelName");
auto & src = getAttr("src"); auto & src = getAttr("src");
if (fs::path{channelName}.filename().string() != channelName) { if (std::filesystem::path{channelName}.filename().string() != channelName) {
throw Error("channelName is not allowed to contain filesystem separators, got %1%", channelName); throw Error("channelName is not allowed to contain filesystem separators, got %1%", channelName);
} }
@ -38,8 +36,8 @@ void builtinUnpackChannel(
auto target = out / channelName; auto target = out / channelName;
try { try {
fs::rename(fileName, target); std::filesystem::rename(fileName, target);
} catch (fs::filesystem_error &) { } catch (std::filesystem::filesystem_error &) {
throw SysError("failed to rename %1% to %2%", fileName, target.string()); throw SysError("failed to rename %1% to %2%", fileName, target.string());
} }
} }

View file

@ -1969,8 +1969,9 @@ void DerivationBuilderImpl::runChild()
if (pathExists(path)) if (pathExists(path))
ss.push_back(path); ss.push_back(path);
if (settings.caFile != "" && pathExists(settings.caFile)) { if (settings.caFile != "") {
Path caFile = settings.caFile; Path caFile = settings.caFile;
if (pathExists(caFile))
pathsInChroot.try_emplace("/etc/ssl/certs/ca-certificates.crt", canonPath(caFile, true), true); pathsInChroot.try_emplace("/etc/ssl/certs/ca-certificates.crt", canonPath(caFile, true), true);
} }
} }

View file

@ -6,10 +6,6 @@
namespace nix { namespace nix {
namespace fs {
using namespace std::filesystem;
}
constexpr static const OsStringView path_var_separator{ constexpr static const OsStringView path_var_separator{
&ExecutablePath::separator, &ExecutablePath::separator,
1, 1,
@ -28,7 +24,7 @@ ExecutablePath ExecutablePath::parse(const OsString & path)
auto strings = path.empty() ? (std::list<OsString>{}) auto strings = path.empty() ? (std::list<OsString>{})
: basicSplitString<std::list<OsString>, OsChar>(path, path_var_separator); : basicSplitString<std::list<OsString>, OsChar>(path, path_var_separator);
std::vector<fs::path> ret; std::vector<std::filesystem::path> ret;
ret.reserve(strings.size()); ret.reserve(strings.size());
std::transform( std::transform(
@ -36,7 +32,7 @@ ExecutablePath ExecutablePath::parse(const OsString & path)
std::make_move_iterator(strings.end()), std::make_move_iterator(strings.end()),
std::back_inserter(ret), std::back_inserter(ret),
[](OsString && str) { [](OsString && str) {
return fs::path{ return std::filesystem::path{
str.empty() str.empty()
// "A zero-length prefix is a legacy feature that // "A zero-length prefix is a legacy feature that
// indicates the current working directory. It // indicates the current working directory. It
@ -62,13 +58,13 @@ OsString ExecutablePath::render() const
return basicConcatStringsSep(path_var_separator, path2); return basicConcatStringsSep(path_var_separator, path2);
} }
std::optional<fs::path> std::optional<std::filesystem::path>
ExecutablePath::findName(const OsString & exe, std::function<bool(const fs::path &)> isExecutable) const ExecutablePath::findName(const OsString & exe, std::function<bool(const std::filesystem::path &)> isExecutable) const
{ {
// "If the pathname being sought contains a <slash>, the search // "If the pathname being sought contains a <slash>, the search
// through the path prefixes shall not be performed." // through the path prefixes shall not be performed."
// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03 // https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03
assert(OsPathTrait<fs::path::value_type>::rfindPathSep(exe) == exe.npos); assert(OsPathTrait<std::filesystem::path::value_type>::rfindPathSep(exe) == exe.npos);
for (auto & dir : directories) { for (auto & dir : directories) {
auto candidate = dir / exe; auto candidate = dir / exe;
@ -79,7 +75,8 @@ ExecutablePath::findName(const OsString & exe, std::function<bool(const fs::path
return std::nullopt; return std::nullopt;
} }
fs::path ExecutablePath::findPath(const fs::path & exe, std::function<bool(const fs::path &)> isExecutable) const std::filesystem::path ExecutablePath::findPath(
const std::filesystem::path & exe, std::function<bool(const std::filesystem::path &)> isExecutable) const
{ {
// "If the pathname being sought contains a <slash>, the search // "If the pathname being sought contains a <slash>, the search
// through the path prefixes shall not be performed." // through the path prefixes shall not be performed."

View file

@ -31,18 +31,6 @@
namespace nix { namespace nix {
namespace fs {
using namespace std::filesystem;
bool symlink_exists(const std::filesystem::path & path) {
try {
return std::filesystem::exists(std::filesystem::symlink_status(path));
} catch (const std::filesystem::filesystem_error & e) {
throw SysError("cannot check existence of %1%", path);
}
}
}
DirectoryIterator::DirectoryIterator(const std::filesystem::path& p) { DirectoryIterator::DirectoryIterator(const std::filesystem::path& p) {
try { try {
// **Attempt to create the underlying directory_iterator** // **Attempt to create the underlying directory_iterator**
@ -73,7 +61,7 @@ DirectoryIterator& DirectoryIterator::operator++() {
bool isAbsolute(PathView path) bool isAbsolute(PathView path)
{ {
return fs::path { path }.is_absolute(); return std::filesystem::path { path }.is_absolute();
} }
@ -122,7 +110,7 @@ Path canonPath(PathView path, bool resolveSymlinks)
throw Error("not an absolute path: '%1%'", path); throw Error("not an absolute path: '%1%'", path);
// For Windows // For Windows
auto rootName = fs::path { path }.root_name(); auto rootName = std::filesystem::path { path }.root_name();
/* This just exists because we cannot set the target of `remaining` /* This just exists because we cannot set the target of `remaining`
(the callback parameter) directly to a newly-constructed string, (the callback parameter) directly to a newly-constructed string,
@ -137,7 +125,7 @@ Path canonPath(PathView path, bool resolveSymlinks)
path, path,
[&followCount, &temp, maxFollow, resolveSymlinks] [&followCount, &temp, maxFollow, resolveSymlinks]
(std::string & result, std::string_view & remaining) { (std::string & result, std::string_view & remaining) {
if (resolveSymlinks && fs::is_symlink(result)) { if (resolveSymlinks && std::filesystem::is_symlink(result)) {
if (++followCount >= maxFollow) if (++followCount >= maxFollow)
throw Error("infinite symlink recursion in path '%1%'", remaining); throw Error("infinite symlink recursion in path '%1%'", remaining);
remaining = (temp = concatStrings(readLink(result), remaining)); remaining = (temp = concatStrings(readLink(result), remaining));
@ -166,7 +154,7 @@ Path dirOf(const PathView path)
Path::size_type pos = OsPathTrait<char>::rfindPathSep(path); Path::size_type pos = OsPathTrait<char>::rfindPathSep(path);
if (pos == path.npos) if (pos == path.npos)
return "."; return ".";
return fs::path{path}.parent_path().string(); return std::filesystem::path{path}.parent_path().string();
} }
@ -189,7 +177,7 @@ std::string_view baseNameOf(std::string_view path)
} }
bool isInDir(const fs::path & path, const fs::path & dir) bool isInDir(const std::filesystem::path & path, const std::filesystem::path & dir)
{ {
/* Note that while the standard doesn't guarantee this, the /* Note that while the standard doesn't guarantee this, the
`lexically_*` functions should do no IO and not throw. */ `lexically_*` functions should do no IO and not throw. */
@ -200,7 +188,7 @@ bool isInDir(const fs::path & path, const fs::path & dir)
} }
bool isDirOrInDir(const fs::path & path, const fs::path & dir) bool isDirOrInDir(const std::filesystem::path & path, const std::filesystem::path & dir)
{ {
return path == dir || isInDir(path, dir); return path == dir || isInDir(path, dir);
} }
@ -243,9 +231,9 @@ std::optional<struct stat> maybeLstat(const Path & path)
} }
bool pathExists(const Path & path) bool pathExists(const std::filesystem::path & path)
{ {
return maybeLstat(path).has_value(); return maybeLstat(path.string()).has_value();
} }
bool pathAccessible(const std::filesystem::path & path) bool pathAccessible(const std::filesystem::path & path)
@ -263,7 +251,7 @@ bool pathAccessible(const std::filesystem::path & path)
Path readLink(const Path & path) Path readLink(const Path & path)
{ {
checkInterrupt(); checkInterrupt();
return fs::read_symlink(path).string(); return std::filesystem::read_symlink(path).string();
} }
@ -381,17 +369,17 @@ void recursiveSync(const Path & path)
/* Otherwise, perform a depth-first traversal of the directory and /* Otherwise, perform a depth-first traversal of the directory and
fsync all the files. */ fsync all the files. */
std::deque<fs::path> dirsToEnumerate; std::deque<std::filesystem::path> dirsToEnumerate;
dirsToEnumerate.push_back(path); dirsToEnumerate.push_back(path);
std::vector<fs::path> dirsToFsync; std::vector<std::filesystem::path> dirsToFsync;
while (!dirsToEnumerate.empty()) { while (!dirsToEnumerate.empty()) {
auto currentDir = dirsToEnumerate.back(); auto currentDir = dirsToEnumerate.back();
dirsToEnumerate.pop_back(); dirsToEnumerate.pop_back();
for (auto & entry : DirectoryIterator(currentDir)) { for (auto & entry : DirectoryIterator(currentDir)) {
auto st = entry.symlink_status(); auto st = entry.symlink_status();
if (fs::is_directory(st)) { if (std::filesystem::is_directory(st)) {
dirsToEnumerate.emplace_back(entry.path()); dirsToEnumerate.emplace_back(entry.path());
} else if (fs::is_regular_file(st)) { } else if (std::filesystem::is_regular_file(st)) {
AutoCloseFD fd = toDescriptor(open(entry.path().string().c_str(), O_RDONLY, 0)); AutoCloseFD fd = toDescriptor(open(entry.path().string().c_str(), O_RDONLY, 0));
if (!fd) if (!fd)
throw SysError("opening file '%1%'", entry.path()); throw SysError("opening file '%1%'", entry.path());
@ -411,7 +399,7 @@ void recursiveSync(const Path & path)
} }
static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & bytesFreed) static void _deletePath(Descriptor parentfd, const std::filesystem::path & path, uint64_t & bytesFreed)
{ {
#ifndef _WIN32 #ifndef _WIN32
checkInterrupt(); checkInterrupt();
@ -485,7 +473,7 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
#endif #endif
} }
static void _deletePath(const fs::path & path, uint64_t & bytesFreed) static void _deletePath(const std::filesystem::path & path, uint64_t & bytesFreed)
{ {
Path dir = dirOf(path.string()); Path dir = dirOf(path.string());
if (dir == "") if (dir == "")
@ -501,7 +489,7 @@ static void _deletePath(const fs::path & path, uint64_t & bytesFreed)
} }
void deletePath(const fs::path & path) void deletePath(const std::filesystem::path & path)
{ {
uint64_t dummy; uint64_t dummy;
deletePath(path, dummy); deletePath(path, dummy);
@ -517,17 +505,17 @@ void createDir(const Path & path, mode_t mode)
throw SysError("creating directory '%1%'", path); throw SysError("creating directory '%1%'", path);
} }
void createDirs(const fs::path & path) void createDirs(const std::filesystem::path & path)
{ {
try { try {
fs::create_directories(path); std::filesystem::create_directories(path);
} catch (fs::filesystem_error & e) { } catch (std::filesystem::filesystem_error & e) {
throw SysError("creating directory '%1%'", path.string()); throw SysError("creating directory '%1%'", path.string());
} }
} }
void deletePath(const fs::path & path, uint64_t & bytesFreed) void deletePath(const std::filesystem::path & path, uint64_t & bytesFreed)
{ {
//Activity act(*logger, lvlDebug, "recursively deleting path '%1%'", path); //Activity act(*logger, lvlDebug, "recursively deleting path '%1%'", path);
bytesFreed = 0; bytesFreed = 0;
@ -552,7 +540,7 @@ AutoDelete::~AutoDelete()
if (recursive) if (recursive)
deletePath(_path); deletePath(_path);
else { else {
fs::remove(_path); std::filesystem::remove(_path);
} }
} }
} catch (...) { } catch (...) {
@ -565,7 +553,7 @@ void AutoDelete::cancel()
del = false; del = false;
} }
void AutoDelete::reset(const fs::path & p, bool recursive) { void AutoDelete::reset(const std::filesystem::path & p, bool recursive) {
_path = p; _path = p;
this->recursive = recursive; this->recursive = recursive;
del = true; del = true;
@ -641,28 +629,28 @@ std::pair<AutoCloseFD, Path> createTempFile(const Path & prefix)
void createSymlink(const Path & target, const Path & link) void createSymlink(const Path & target, const Path & link)
{ {
try { try {
fs::create_symlink(target, link); std::filesystem::create_symlink(target, link);
} catch (fs::filesystem_error & e) { } catch (std::filesystem::filesystem_error & e) {
throw SysError("creating symlink '%1%' -> '%2%'", link, target); throw SysError("creating symlink '%1%' -> '%2%'", link, target);
} }
} }
void replaceSymlink(const fs::path & target, const fs::path & link) void replaceSymlink(const std::filesystem::path & target, const std::filesystem::path & link)
{ {
for (unsigned int n = 0; true; n++) { for (unsigned int n = 0; true; n++) {
auto tmp = link.parent_path() / fs::path{fmt(".%d_%s", n, link.filename().string())}; auto tmp = link.parent_path() /std::filesystem::path{fmt(".%d_%s", n, link.filename().string())};
tmp = tmp.lexically_normal(); tmp = tmp.lexically_normal();
try { try {
fs::create_symlink(target, tmp); std::filesystem::create_symlink(target, tmp);
} catch (fs::filesystem_error & e) { } catch (std::filesystem::filesystem_error & e) {
if (e.code() == std::errc::file_exists) continue; if (e.code() == std::errc::file_exists) continue;
throw SysError("creating symlink %1% -> %2%", tmp, target); throw SysError("creating symlink %1% -> %2%", tmp, target);
} }
try { try {
fs::rename(tmp, link); std::filesystem::rename(tmp, link);
} catch (fs::filesystem_error & e) { } catch (std::filesystem::filesystem_error & e) {
if (e.code() == std::errc::file_exists) continue; if (e.code() == std::errc::file_exists) continue;
throw SysError("renaming %1% to %2%", tmp, link); throw SysError("renaming %1% to %2%", tmp, link);
} }
@ -672,25 +660,24 @@ void replaceSymlink(const fs::path & target, const fs::path & link)
} }
} }
void setWriteTime(const fs::path & path, const struct stat & st) void setWriteTime(const std::filesystem::path & path, const struct stat & st)
{ {
setWriteTime(path, st.st_atime, st.st_mtime, S_ISLNK(st.st_mode)); setWriteTime(path, st.st_atime, st.st_mtime, S_ISLNK(st.st_mode));
} }
void copyFile(const fs::path & from, const fs::path & to, bool andDelete) void copyFile(const std::filesystem::path & from, const std::filesystem::path & to, bool andDelete)
{ {
auto fromStatus = fs::symlink_status(from); auto fromStatus =std::filesystem::symlink_status(from);
// Mark the directory as writable so that we can delete its children // Mark the directory as writable so that we can delete its children
if (andDelete && fs::is_directory(fromStatus)) { if (andDelete &&std::filesystem::is_directory(fromStatus)) {
fs::permissions(from, fs::perms::owner_write, fs::perm_options::add | fs::perm_options::nofollow); std::filesystem::permissions(from, std::filesystem::perms::owner_write, std::filesystem::perm_options::add | std::filesystem::perm_options::nofollow);
} }
if (std::filesystem::is_symlink(fromStatus) ||std::filesystem::is_regular_file(fromStatus)) {
if (fs::is_symlink(fromStatus) || fs::is_regular_file(fromStatus)) { std::filesystem::copy(from, to, std::filesystem::copy_options::copy_symlinks | std::filesystem::copy_options::overwrite_existing);
fs::copy(from, to, fs::copy_options::copy_symlinks | fs::copy_options::overwrite_existing); } else if (std::filesystem::is_directory(fromStatus)) {
} else if (fs::is_directory(fromStatus)) { std::filesystem::create_directory(to);
fs::create_directory(to);
for (auto & entry : DirectoryIterator(from)) { for (auto & entry : DirectoryIterator(from)) {
copyFile(entry, to / entry.path().filename(), andDelete); copyFile(entry, to / entry.path().filename(), andDelete);
} }
@ -700,9 +687,9 @@ void copyFile(const fs::path & from, const fs::path & to, bool andDelete)
setWriteTime(to, lstat(from.string().c_str())); setWriteTime(to, lstat(from.string().c_str()));
if (andDelete) { if (andDelete) {
if (!fs::is_symlink(fromStatus)) if (!std::filesystem::is_symlink(fromStatus))
fs::permissions(from, fs::perms::owner_write, fs::perm_options::add | fs::perm_options::nofollow); std::filesystem::permissions(from, std::filesystem::perms::owner_write, std::filesystem::perm_options::add | std::filesystem::perm_options::nofollow);
fs::remove(from); std::filesystem::remove(from);
} }
} }
@ -710,18 +697,18 @@ void moveFile(const Path & oldName, const Path & newName)
{ {
try { try {
std::filesystem::rename(oldName, newName); std::filesystem::rename(oldName, newName);
} catch (fs::filesystem_error & e) { } catch (std::filesystem::filesystem_error & e) {
auto oldPath = fs::path(oldName); auto oldPath = std::filesystem::path(oldName);
auto newPath = fs::path(newName); auto newPath = std::filesystem::path(newName);
// For the move to be as atomic as possible, copy to a temporary // For the move to be as atomic as possible, copy to a temporary
// directory // directory
fs::path temp = createTempDir( std::filesystem::path temp = createTempDir(
os_string_to_string(PathViewNG { newPath.parent_path() }), os_string_to_string(PathViewNG { newPath.parent_path() }),
"rename-tmp"); "rename-tmp");
Finally removeTemp = [&]() { fs::remove(temp); }; Finally removeTemp = [&]() { std::filesystem::remove(temp); };
auto tempCopyTarget = temp / "copy-target"; auto tempCopyTarget = temp / "copy-target";
if (e.code().value() == EXDEV) { if (e.code().value() == EXDEV) {
fs::remove(newPath); std::filesystem::remove(newPath);
warn("cant rename %s as %s, copying instead", oldName, newName); warn("cant rename %s as %s, copying instead", oldName, newName);
copyFile(oldPath, tempCopyTarget, true); copyFile(oldPath, tempCopyTarget, true);
std::filesystem::rename( std::filesystem::rename(
@ -733,7 +720,7 @@ void moveFile(const Path & oldName, const Path & newName)
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
bool isExecutableFileAmbient(const fs::path & exe) { bool isExecutableFileAmbient(const std::filesystem::path & exe) {
// Check file type, because directory being executable means // Check file type, because directory being executable means
// something completely different. // something completely different.
// `is_regular_file` follows symlinks before checking. // `is_regular_file` follows symlinks before checking.
@ -757,12 +744,12 @@ std::filesystem::path makeParentCanonical(const std::filesystem::path & rawPath)
return parent; return parent;
} }
return std::filesystem::canonical(parent) / path.filename(); return std::filesystem::canonical(parent) / path.filename();
} catch (fs::filesystem_error & e) { } catch (std::filesystem::filesystem_error & e) {
throw SysError("canonicalising parent path of '%1%'", path); throw SysError("canonicalising parent path of '%1%'", path);
} }
} }
bool chmodIfNeeded(const fs::path & path, mode_t mode, mode_t mask) bool chmodIfNeeded(const std::filesystem::path & path, mode_t mode, mode_t mask)
{ {
auto pathString = path.string(); auto pathString = path.string();
auto prevMode = lstat(pathString).st_mode; auto prevMode = lstat(pathString).st_mode;

View file

@ -126,26 +126,8 @@ std::optional<struct stat> maybeLstat(const Path & path);
/** /**
* @return true iff the given path exists. * @return true iff the given path exists.
*
* In the process of being deprecated for `fs::symlink_exists`.
*/ */
bool pathExists(const Path & path); bool pathExists(const std::filesystem::path & path);
namespace fs {
/**
* TODO: we may actually want to use pathExists instead of this function
* ```
* symlink_exists(p) = std::filesystem::exists(std::filesystem::symlink_status(p))
* ```
* Missing convenience analogous to
* ```
* std::filesystem::exists(p) = std::filesystem::exists(std::filesystem::status(p))
* ```
*/
bool symlink_exists(const std::filesystem::path & path);
} // namespace fs
/** /**
* Canonicalize a path except for the last component. * Canonicalize a path except for the last component.

View file

@ -8,10 +8,6 @@
namespace nix { namespace nix {
namespace fs {
using namespace std::filesystem;
}
namespace { namespace {
int callback_open(struct archive *, void * self) int callback_open(struct archive *, void * self)
@ -127,7 +123,7 @@ TarArchive::~TarArchive()
archive_read_free(this->archive); archive_read_free(this->archive);
} }
static void extract_archive(TarArchive & archive, const fs::path & destDir) static void extract_archive(TarArchive & archive, const std::filesystem::path & destDir)
{ {
int flags = ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_SECURE_SYMLINKS | ARCHIVE_EXTRACT_SECURE_NODOTDOT; int flags = ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_SECURE_SYMLINKS | ARCHIVE_EXTRACT_SECURE_NODOTDOT;
@ -162,7 +158,7 @@ static void extract_archive(TarArchive & archive, const fs::path & destDir)
archive.close(); archive.close();
} }
void unpackTarfile(Source & source, const fs::path & destDir) void unpackTarfile(Source & source, const std::filesystem::path & destDir)
{ {
auto archive = TarArchive(source); auto archive = TarArchive(source);
@ -170,7 +166,7 @@ void unpackTarfile(Source & source, const fs::path & destDir)
extract_archive(archive, destDir); extract_archive(archive, destDir);
} }
void unpackTarfile(const fs::path & tarFile, const fs::path & destDir) void unpackTarfile(const std::filesystem::path & tarFile, const std::filesystem::path & destDir)
{ {
auto archive = TarArchive(tarFile); auto archive = TarArchive(tarFile);

View file

@ -14,16 +14,13 @@
namespace nix { namespace nix {
namespace fs {
using namespace std::filesystem;
}
Descriptor openDirectory(const std::filesystem::path & path) Descriptor openDirectory(const std::filesystem::path & path)
{ {
return open(path.c_str(), O_RDONLY | O_DIRECTORY); return open(path.c_str(), O_RDONLY | O_DIRECTORY);
} }
void setWriteTime(const fs::path & path, time_t accessedTime, time_t modificationTime, std::optional<bool> optIsSymlink) void setWriteTime(
const std::filesystem::path & path, time_t accessedTime, time_t modificationTime, std::optional<bool> optIsSymlink)
{ {
// Would be nice to use std::filesystem unconditionally, but // Would be nice to use std::filesystem unconditionally, but
// doesn't support access time just modification time. // doesn't support access time just modification time.
@ -57,7 +54,7 @@ void setWriteTime(const fs::path & path, time_t accessedTime, time_t modificatio
if (lutimes(path.c_str(), times) == -1) if (lutimes(path.c_str(), times) == -1)
throw SysError("changing modification time of %s", path); throw SysError("changing modification time of %s", path);
# else # else
bool isSymlink = optIsSymlink ? *optIsSymlink : fs::is_symlink(path); bool isSymlink = optIsSymlink ? *optIsSymlink : std::filesystem::is_symlink(path);
if (!isSymlink) { if (!isSymlink) {
if (utimes(path.c_str(), times) == -1) if (utimes(path.c_str(), times) == -1)

View file

@ -9,8 +9,6 @@
namespace nix { namespace nix {
namespace fs { using namespace std::filesystem; }
std::string getUserName() std::string getUserName()
{ {
auto pw = getpwuid(geteuid()); auto pw = getpwuid(geteuid());

View file

@ -3,13 +3,10 @@
#ifdef _WIN32 #ifdef _WIN32
namespace nix { namespace nix {
namespace fs { void setWriteTime(
using namespace std::filesystem; const std::filesystem::path & path, time_t accessedTime, time_t modificationTime, std::optional<bool> optIsSymlink)
}
void setWriteTime(const fs::path & path, time_t accessedTime, time_t modificationTime, std::optional<bool> optIsSymlink)
{ {
// FIXME use `fs::last_write_time`. // FIXME use `std::filesystem::last_write_time`.
// //
// Would be nice to use std::filesystem unconditionally, but // Would be nice to use std::filesystem unconditionally, but
// doesn't support access time just modification time. // doesn't support access time just modification time.

View file

@ -24,7 +24,7 @@ bool dryRun = false;
* Of course, this makes rollbacks to before this point in time * Of course, this makes rollbacks to before this point in time
* impossible. */ * impossible. */
void removeOldGenerations(fs::path dir) void removeOldGenerations(std::filesystem::path dir)
{ {
if (access(dir.string().c_str(), R_OK) != 0) return; if (access(dir.string().c_str(), R_OK) != 0) return;
@ -36,11 +36,11 @@ void removeOldGenerations(fs::path dir)
auto path = i.path().string(); auto path = i.path().string();
auto type = i.symlink_status().type(); auto type = i.symlink_status().type();
if (type == fs::file_type::symlink && canWrite) { if (type == std::filesystem::file_type::symlink && canWrite) {
std::string link; std::string link;
try { try {
link = readLink(path); link = readLink(path);
} catch (fs::filesystem_error & e) { } catch (std::filesystem::filesystem_error & e) {
if (e.code() == std::errc::no_such_file_or_directory) continue; if (e.code() == std::errc::no_such_file_or_directory) continue;
throw; throw;
} }
@ -52,7 +52,7 @@ void removeOldGenerations(fs::path dir)
} else } else
deleteOldGenerations(path, dryRun); deleteOldGenerations(path, dryRun);
} }
} else if (type == fs::file_type::directory) { } else if (type == std::filesystem::file_type::directory) {
removeOldGenerations(path); removeOldGenerations(path);
} }
} }
@ -84,10 +84,10 @@ static int main_nix_collect_garbage(int argc, char * * argv)
}); });
if (removeOld) { if (removeOld) {
std::set<fs::path> dirsToClean = { std::set<std::filesystem::path> dirsToClean = {
profilesDir(), profilesDir(),
fs::path{settings.nixStateDir} / "profiles", std::filesystem::path{settings.nixStateDir} / "profiles",
fs::path{getDefaultProfile()}.parent_path(), std::filesystem::path{getDefaultProfile()}.parent_path(),
}; };
for (auto & dir : dirsToClean) for (auto & dir : dirsToClean)
removeOldGenerations(dir); removeOldGenerations(dir);

View file

@ -80,7 +80,7 @@ struct CmdBundle : InstallableValueCommand
auto [bundlerFlakeRef, bundlerName, extendedOutputsSpec] = auto [bundlerFlakeRef, bundlerName, extendedOutputsSpec] =
parseFlakeRefWithFragmentAndExtendedOutputsSpec( parseFlakeRefWithFragmentAndExtendedOutputsSpec(
fetchSettings, bundler, fs::current_path().string()); fetchSettings, bundler, std::filesystem::current_path().string());
const flake::LockFlags lockFlags{ .writeLockFile = false }; const flake::LockFlags lockFlags{ .writeLockFile = false };
InstallableFlake bundler{this, InstallableFlake bundler{this,
evalState, std::move(bundlerFlakeRef), bundlerName, std::move(extendedOutputsSpec), evalState, std::move(bundlerFlakeRef), bundlerName, std::move(extendedOutputsSpec),

View file

@ -78,12 +78,12 @@ struct CmdConfigCheck : StoreCommand
bool checkNixInPath() bool checkNixInPath()
{ {
std::set<fs::path> dirs; std::set<std::filesystem::path> dirs;
for (auto & dir : ExecutablePath::load().directories) { for (auto & dir : ExecutablePath::load().directories) {
auto candidate = dir / "nix-env"; auto candidate = dir / "nix-env";
if (fs::exists(candidate)) if (std::filesystem::exists(candidate))
dirs.insert(fs::canonical(candidate).parent_path() ); dirs.insert(std::filesystem::canonical(candidate).parent_path() );
} }
if (dirs.size() != 1) { if (dirs.size() != 1) {
@ -99,12 +99,12 @@ struct CmdConfigCheck : StoreCommand
bool checkProfileRoots(ref<Store> store) bool checkProfileRoots(ref<Store> store)
{ {
std::set<fs::path> dirs; std::set<std::filesystem::path> dirs;
for (auto & dir : ExecutablePath::load().directories) { for (auto & dir : ExecutablePath::load().directories) {
auto profileDir = dir.parent_path(); auto profileDir = dir.parent_path();
try { try {
auto userEnv = fs::weakly_canonical(profileDir); auto userEnv = std::filesystem::weakly_canonical(profileDir);
auto noContainsProfiles = [&]{ auto noContainsProfiles = [&]{
for (auto && part : profileDir) for (auto && part : profileDir)
@ -114,8 +114,8 @@ struct CmdConfigCheck : StoreCommand
if (store->isStorePath(userEnv.string()) && hasSuffix(userEnv.string(), "user-environment")) { if (store->isStorePath(userEnv.string()) && hasSuffix(userEnv.string(), "user-environment")) {
while (noContainsProfiles() && std::filesystem::is_symlink(profileDir)) while (noContainsProfiles() && std::filesystem::is_symlink(profileDir))
profileDir = fs::weakly_canonical( profileDir = std::filesystem::weakly_canonical(
profileDir.parent_path() / fs::read_symlink(profileDir)); profileDir.parent_path() / std::filesystem::read_symlink(profileDir));
if (noContainsProfiles()) if (noContainsProfiles())
dirs.insert(dir); dirs.insert(dir);

View file

@ -345,7 +345,7 @@ struct Common : InstallableCommand, MixProfile
ref<Store> store, ref<Store> store,
const BuildEnvironment & buildEnvironment, const BuildEnvironment & buildEnvironment,
const std::filesystem::path & tmpDir, const std::filesystem::path & tmpDir,
const std::filesystem::path & outputsDir = fs::path { fs::current_path() } / "outputs") const std::filesystem::path & outputsDir = std::filesystem::path { std::filesystem::current_path() } / "outputs")
{ {
// A list of colon-separated environment variables that should be // A list of colon-separated environment variables that should be
// prepended to, rather than overwritten, in order to keep the shell usable. // prepended to, rather than overwritten, in order to keep the shell usable.

View file

@ -16,7 +16,7 @@ struct CmdEval : MixJSON, InstallableValueCommand, MixReadOnlyOption
{ {
bool raw = false; bool raw = false;
std::optional<std::string> apply; std::optional<std::string> apply;
std::optional<fs::path> writeTo; std::optional<std::filesystem::path> writeTo;
CmdEval() : InstallableValueCommand() CmdEval() : InstallableValueCommand()
{ {
@ -76,19 +76,19 @@ struct CmdEval : MixJSON, InstallableValueCommand, MixReadOnlyOption
if (writeTo) { if (writeTo) {
logger->stop(); logger->stop();
if (fs::symlink_exists(*writeTo)) if (pathExists(*writeTo))
throw Error("path '%s' already exists", writeTo->string()); throw Error("path '%s' already exists", writeTo->string());
std::function<void(Value & v, const PosIdx pos, const fs::path & path)> recurse; std::function<void(Value & v, const PosIdx pos, const std::filesystem::path & path)> recurse;
recurse = [&](Value & v, const PosIdx pos, const fs::path & path) recurse = [&](Value & v, const PosIdx pos, const std::filesystem::path & path)
{ {
state->forceValue(v, pos); state->forceValue(v, pos);
if (v.type() == nString) if (v.type() == nString)
// FIXME: disallow strings with contexts? // FIXME: disallow strings with contexts?
writeFile(path.string(), v.string_view()); writeFile(path.string(), v.string_view());
else if (v.type() == nAttrs) { else if (v.type() == nAttrs) {
[[maybe_unused]] bool directoryCreated = fs::create_directory(path); [[maybe_unused]] bool directoryCreated = std::filesystem::create_directory(path);
// Directory should not already exist // Directory should not already exist
assert(directoryCreated); assert(directoryCreated);
for (auto & attr : *v.attrs()) { for (auto & attr : *v.attrs()) {

View file

@ -54,7 +54,7 @@ public:
FlakeRef getFlakeRef() FlakeRef getFlakeRef()
{ {
return parseFlakeRef(fetchSettings, flakeUrl, fs::current_path().string()); //FIXME return parseFlakeRef(fetchSettings, flakeUrl, std::filesystem::current_path().string()); //FIXME
} }
LockedFlake lockFlake() LockedFlake lockFlake()
@ -66,7 +66,7 @@ public:
{ {
return { return {
// Like getFlakeRef but with expandTilde calld first // Like getFlakeRef but with expandTilde calld first
parseFlakeRef(fetchSettings, expandTilde(flakeUrl), fs::current_path().string()) parseFlakeRef(fetchSettings, expandTilde(flakeUrl), std::filesystem::current_path().string())
}; };
} }
}; };
@ -885,7 +885,7 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
auto evalState = getEvalState(); auto evalState = getEvalState();
auto [templateFlakeRef, templateName] = parseFlakeRefWithFragment( auto [templateFlakeRef, templateName] = parseFlakeRefWithFragment(
fetchSettings, templateUrl, fs::current_path().string()); fetchSettings, templateUrl, std::filesystem::current_path().string());
auto installable = InstallableFlake(nullptr, auto installable = InstallableFlake(nullptr,
evalState, std::move(templateFlakeRef), templateName, ExtendedOutputsSpec::Default(), evalState, std::move(templateFlakeRef), templateName, ExtendedOutputsSpec::Default(),
@ -899,11 +899,11 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
NixStringContext context; NixStringContext context;
auto templateDir = evalState->coerceToPath(noPos, templateDirAttr, context, ""); auto templateDir = evalState->coerceToPath(noPos, templateDirAttr, context, "");
std::vector<fs::path> changedFiles; std::vector<std::filesystem::path> changedFiles;
std::vector<fs::path> conflictedFiles; std::vector<std::filesystem::path> conflictedFiles;
std::function<void(const SourcePath & from, const fs::path & to)> copyDir; std::function<void(const SourcePath & from, const std::filesystem::path & to)> copyDir;
copyDir = [&](const SourcePath & from, const fs::path & to) copyDir = [&](const SourcePath & from, const std::filesystem::path & to)
{ {
createDirs(to); createDirs(to);
@ -912,12 +912,12 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
auto from2 = from / name; auto from2 = from / name;
auto to2 = to / name; auto to2 = to / name;
auto st = from2.lstat(); auto st = from2.lstat();
auto to_st = fs::symlink_status(to2); auto to_st = std::filesystem::symlink_status(to2);
if (st.type == SourceAccessor::tDirectory) if (st.type == SourceAccessor::tDirectory)
copyDir(from2, to2); copyDir(from2, to2);
else if (st.type == SourceAccessor::tRegular) { else if (st.type == SourceAccessor::tRegular) {
auto contents = from2.readFile(); auto contents = from2.readFile();
if (fs::exists(to_st)) { if (std::filesystem::exists(to_st)) {
auto contents2 = readFile(to2.string()); auto contents2 = readFile(to2.string());
if (contents != contents2) { if (contents != contents2) {
printError("refusing to overwrite existing file '%s'\n please merge it manually with '%s'", to2.string(), from2); printError("refusing to overwrite existing file '%s'\n please merge it manually with '%s'", to2.string(), from2);
@ -931,8 +931,8 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
} }
else if (st.type == SourceAccessor::tSymlink) { else if (st.type == SourceAccessor::tSymlink) {
auto target = from2.readLink(); auto target = from2.readLink();
if (fs::exists(to_st)) { if (std::filesystem::exists(to_st)) {
if (fs::read_symlink(to2) != target) { if (std::filesystem::read_symlink(to2) != target) {
printError("refusing to overwrite existing file '%s'\n please merge it manually with '%s'", to2.string(), from2); printError("refusing to overwrite existing file '%s'\n please merge it manually with '%s'", to2.string(), from2);
conflictedFiles.push_back(to2); conflictedFiles.push_back(to2);
} else { } else {
@ -951,7 +951,7 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
copyDir(templateDir, flakeDir); copyDir(templateDir, flakeDir);
if (!changedFiles.empty() && fs::exists(std::filesystem::path{flakeDir} / ".git")) { if (!changedFiles.empty() && std::filesystem::exists(std::filesystem::path{flakeDir} / ".git")) {
Strings args = { "-C", flakeDir, "add", "--intent-to-add", "--force", "--" }; Strings args = { "-C", flakeDir, "add", "--intent-to-add", "--force", "--" };
for (auto & s : changedFiles) args.emplace_back(s.string()); for (auto & s : changedFiles) args.emplace_back(s.string());
runProgram("git", true, args); runProgram("git", true, args);

View file

@ -172,7 +172,7 @@ void chrootHelper(int argc, char * * argv)
if (!pathExists(storeDir)) { if (!pathExists(storeDir)) {
// FIXME: Use overlayfs? // FIXME: Use overlayfs?
fs::path tmpDir = createTempDir(); std::filesystem::path tmpDir = createTempDir();
createDirs(tmpDir + storeDir); createDirs(tmpDir + storeDir);
@ -182,15 +182,15 @@ void chrootHelper(int argc, char * * argv)
for (const auto & entry : DirectoryIterator{"/"}) { for (const auto & entry : DirectoryIterator{"/"}) {
checkInterrupt(); checkInterrupt();
const auto & src = entry.path(); const auto & src = entry.path();
fs::path dst = tmpDir / entry.path().filename(); std::filesystem::path dst = tmpDir / entry.path().filename();
if (pathExists(dst)) continue; if (pathExists(dst)) continue;
auto st = entry.symlink_status(); auto st = entry.symlink_status();
if (fs::is_directory(st)) { if (std::filesystem::is_directory(st)) {
if (mkdir(dst.c_str(), 0700) == -1) if (mkdir(dst.c_str(), 0700) == -1)
throw SysError("creating directory '%s'", dst); throw SysError("creating directory '%s'", dst);
if (mount(src.c_str(), dst.c_str(), "", MS_BIND | MS_REC, 0) == -1) if (mount(src.c_str(), dst.c_str(), "", MS_BIND | MS_REC, 0) == -1)
throw SysError("mounting '%s' on '%s'", src, dst); throw SysError("mounting '%s' on '%s'", src, dst);
} else if (fs::is_symlink(st)) } else if (std::filesystem::is_symlink(st))
createSymlink(readLink(src), dst); createSymlink(readLink(src), dst);
} }
@ -208,9 +208,9 @@ void chrootHelper(int argc, char * * argv)
if (mount(realStoreDir.c_str(), storeDir.c_str(), "", MS_BIND, 0) == -1) if (mount(realStoreDir.c_str(), storeDir.c_str(), "", MS_BIND, 0) == -1)
throw SysError("mounting '%s' on '%s'", realStoreDir, storeDir); throw SysError("mounting '%s' on '%s'", realStoreDir, storeDir);
writeFile(fs::path{"/proc/self/setgroups"}, "deny"); writeFile(std::filesystem::path{"/proc/self/setgroups"}, "deny");
writeFile(fs::path{"/proc/self/uid_map"}, fmt("%d %d %d", uid, uid, 1)); writeFile(std::filesystem::path{"/proc/self/uid_map"}, fmt("%d %d %d", uid, uid, 1));
writeFile(fs::path{"/proc/self/gid_map"}, fmt("%d %d %d", gid, gid, 1)); writeFile(std::filesystem::path{"/proc/self/gid_map"}, fmt("%d %d %d", gid, gid, 1));
#ifdef __linux__ #ifdef __linux__
if (system != "") if (system != "")

View file

@ -7,32 +7,28 @@
namespace nix { namespace nix {
namespace fs { std::filesystem::path getNixBin(std::optional<std::string_view> binaryNameOpt)
using namespace std::filesystem;
}
fs::path getNixBin(std::optional<std::string_view> binaryNameOpt)
{ {
auto getBinaryName = [&] { return binaryNameOpt ? *binaryNameOpt : "nix"; }; auto getBinaryName = [&] { return binaryNameOpt ? *binaryNameOpt : "nix"; };
// If the environment variable is set, use it unconditionally. // If the environment variable is set, use it unconditionally.
if (auto envOpt = getEnvNonEmpty("NIX_BIN_DIR")) if (auto envOpt = getEnvNonEmpty("NIX_BIN_DIR"))
return fs::path{*envOpt} / std::string{getBinaryName()}; return std::filesystem::path{*envOpt} / std::string{getBinaryName()};
// Try OS tricks, if available, to get to the path of this Nix, and // Try OS tricks, if available, to get to the path of this Nix, and
// see if we can find the right executable next to that. // see if we can find the right executable next to that.
if (auto selfOpt = getSelfExe()) { if (auto selfOpt = getSelfExe()) {
fs::path path{*selfOpt}; std::filesystem::path path{*selfOpt};
if (binaryNameOpt) if (binaryNameOpt)
path = path.parent_path() / std::string{*binaryNameOpt}; path = path.parent_path() / std::string{*binaryNameOpt};
if (fs::exists(path)) if (std::filesystem::exists(path))
return path; return path;
} }
// If `nix` exists at the hardcoded fallback path, use it. // If `nix` exists at the hardcoded fallback path, use it.
{ {
auto path = fs::path{NIX_BIN_DIR} / std::string{getBinaryName()}; auto path = std::filesystem::path{NIX_BIN_DIR} / std::string{getBinaryName()};
if (fs::exists(path)) if (std::filesystem::exists(path))
return path; return path;
} }