diff --git a/src/libstore/remote-fs-accessor.cc b/src/libstore/remote-fs-accessor.cc index da232de2efc..0fd0945da02 100644 --- a/src/libstore/remote-fs-accessor.cc +++ b/src/libstore/remote-fs-accessor.cc @@ -21,7 +21,9 @@ RemoteFSAccessor::RemoteFSAccessor( std::filesystem::path RemoteFSAccessor::makeCacheFile(std::string_view hashPart, const std::string & ext) { assert(cacheDir); - return (*cacheDir / hashPart) + "." + ext; + auto res = (*cacheDir / hashPart); + res.concat(concatStrings(".", ext)); + return res; } ref RemoteFSAccessor::addToCache(std::string_view hashPart, std::string && nar) diff --git a/src/libstore/windows/pathlocks.cc b/src/libstore/windows/pathlocks.cc index 32d9e7c0fa8..e37b1e15b56 100644 --- a/src/libstore/windows/pathlocks.cc +++ b/src/libstore/windows/pathlocks.cc @@ -7,7 +7,6 @@ # include # include # include -# include "nix/util/windows-error.hh" namespace nix { diff --git a/src/libutil/file-descriptor.cc b/src/libutil/file-descriptor.cc index 6e07e6e8818..6c6b1f9d1da 100644 --- a/src/libutil/file-descriptor.cc +++ b/src/libutil/file-descriptor.cc @@ -6,7 +6,6 @@ #ifdef _WIN32 # include # include -# include "nix/util/windows-error.hh" #endif namespace nix { diff --git a/src/libutil/fs-sink.cc b/src/libutil/fs-sink.cc index 521a10c9a77..2ba3d98bc12 100644 --- a/src/libutil/fs-sink.cc +++ b/src/libutil/fs-sink.cc @@ -7,7 +7,6 @@ #ifdef _WIN32 # include # include "nix/util/file-path.hh" -# include "nix/util/windows-error.hh" #endif #include "util-config-private.hh" diff --git a/src/libutil/include/nix/util/error.hh b/src/libutil/include/nix/util/error.hh index af1bd68af6a..542fc8559c0 100644 --- a/src/libutil/include/nix/util/error.hh +++ b/src/libutil/include/nix/util/error.hh @@ -27,6 +27,9 @@ #include #include #include +#ifdef _WIN32 +# include +#endif namespace nix { @@ -288,25 +291,6 @@ public: } }; -#ifdef _WIN32 -namespace windows { -class WinError; -} -#endif - -/** - * Convenience alias for when we use a `errno`-based error handling - * function on Unix, and `GetLastError()`-based error handling on on - * Windows. - */ -using NativeSysError = -#ifdef _WIN32 - windows::WinError -#else - SysError -#endif - ; - /** * Throw an exception for the purpose of checking that exception * handling works; see 'initLibUtil()'. @@ -326,4 +310,67 @@ void panic(std::string_view msg); */ [[gnu::noinline, gnu::cold, noreturn]] void unreachable(std::source_location loc = std::source_location::current()); +#ifdef _WIN32 + +namespace windows { + +/** + * Windows Error type. + * + * Unless you need to catch a specific error number, don't catch this in + * portable code. Catch `SystemError` instead. + */ +class WinError : public SystemError +{ +public: + DWORD lastError; + + /** + * Construct using the explicitly-provided error number. + * `FormatMessageA` will be used to try to add additional + * information to the message. + */ + template + WinError(DWORD lastError, const Args &... args) + : SystemError("") + , lastError(lastError) + { + auto hf = HintFmt(args...); + err.msg = HintFmt("%1%: %2%", Uncolored(hf.str()), renderError(lastError)); + } + + /** + * Construct using `GetLastError()` and the ambient "last error". + * + * Be sure to not perform another last-error-modifying operation + * before calling this constructor! + */ + template + WinError(const Args &... args) + : WinError(GetLastError(), args...) + { + } + +private: + + std::string renderError(DWORD lastError); +}; + +} // namespace windows + +#endif + +/** + * Convenience alias for when we use a `errno`-based error handling + * function on Unix, and `GetLastError()`-based error handling on on + * Windows. + */ +using NativeSysError = +#ifdef _WIN32 + windows::WinError +#else + SysError +#endif + ; + } // namespace nix diff --git a/src/libutil/include/nix/util/file-system.hh b/src/libutil/include/nix/util/file-system.hh index ab1a90647ed..f27394b0861 100644 --- a/src/libutil/include/nix/util/file-system.hh +++ b/src/libutil/include/nix/util/file-system.hh @@ -164,6 +164,13 @@ std::filesystem::path readLink(const std::filesystem::path & path); */ Descriptor openDirectory(const std::filesystem::path & path); +/** + * Open a `Descriptor` with read-only access to the given file. + * + * @note For directories use @ref openDirectory. + */ +Descriptor openFileReadonly(const std::filesystem::path & path); + /** * Read the contents of a file into a string. */ diff --git a/src/libutil/include/nix/util/muxable-pipe.hh b/src/libutil/include/nix/util/muxable-pipe.hh index f15c8e5f82d..f0f762d60cb 100644 --- a/src/libutil/include/nix/util/muxable-pipe.hh +++ b/src/libutil/include/nix/util/muxable-pipe.hh @@ -10,7 +10,6 @@ # include #else # include -# include "nix/util/windows-error.hh" #endif namespace nix { diff --git a/src/libutil/include/nix/util/nar-accessor.hh b/src/libutil/include/nix/util/nar-accessor.hh index 745c79f607b..0a801711b46 100644 --- a/src/libutil/include/nix/util/nar-accessor.hh +++ b/src/libutil/include/nix/util/nar-accessor.hh @@ -4,6 +4,7 @@ #include "nix/util/memory-source-accessor.hh" #include +#include #include @@ -30,7 +31,7 @@ using GetNarBytes = std::function; /** * The canonical GetNarBytes function for a seekable Source. */ -GetNarBytes seekableGetNarBytes(const Path & path); +GetNarBytes seekableGetNarBytes(const std::filesystem::path & path); GetNarBytes seekableGetNarBytes(Descriptor fd); diff --git a/src/libutil/nar-accessor.cc b/src/libutil/nar-accessor.cc index e43d43aac0b..7387007e63b 100644 --- a/src/libutil/nar-accessor.cc +++ b/src/libutil/nar-accessor.cc @@ -1,6 +1,7 @@ #include "nix/util/nar-accessor.hh" #include "nix/util/file-descriptor.hh" #include "nix/util/archive.hh" +#include "nix/util/error.hh" #include #include @@ -263,17 +264,11 @@ ref makeLazyNarAccessor(Source & source, GetNarBytes getNarBytes return make_ref(source, getNarBytes); } -GetNarBytes seekableGetNarBytes(const Path & path) +GetNarBytes seekableGetNarBytes(const std::filesystem::path & path) { - AutoCloseFD fd = toDescriptor(open( - path.c_str(), - O_RDONLY -#ifdef O_CLOEXEC - | O_CLOEXEC -#endif - )); + AutoCloseFD fd = openFileReadonly(path); if (!fd) - throw SysError("opening NAR cache file '%s'", path); + throw NativeSysError("opening NAR cache file '%s'", path); return [inner = seekableGetNarBytes(fd.get()), fd = make_ref(std::move(fd))]( uint64_t offset, uint64_t length) { return inner(offset, length); }; diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc index 403539dcc4f..8297f559994 100644 --- a/src/libutil/serialise.cc +++ b/src/libutil/serialise.cc @@ -13,7 +13,6 @@ #ifdef _WIN32 # include -# include "nix/util/windows-error.hh" #else # include #endif diff --git a/src/libutil/unix/file-system.cc b/src/libutil/unix/file-system.cc index 692f7fd075d..cebcc4fab2d 100644 --- a/src/libutil/unix/file-system.cc +++ b/src/libutil/unix/file-system.cc @@ -27,6 +27,11 @@ Descriptor openDirectory(const std::filesystem::path & path) return open(path.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC); } +Descriptor openFileReadonly(const std::filesystem::path & path) +{ + return open(path.c_str(), O_RDONLY | O_CLOEXEC); +} + std::filesystem::path defaultTempDir() { return getEnvNonEmpty("TMPDIR").value_or("/tmp"); diff --git a/src/libutil/windows/current-process.cc b/src/libutil/windows/current-process.cc index 4bc866bb3ef..d4392e2279d 100644 --- a/src/libutil/windows/current-process.cc +++ b/src/libutil/windows/current-process.cc @@ -1,5 +1,5 @@ #include "nix/util/current-process.hh" -#include "nix/util/windows-error.hh" +#include "nix/util/error.hh" #include #ifdef _WIN32 diff --git a/src/libutil/windows/file-descriptor.cc b/src/libutil/windows/file-descriptor.cc index 57994eac00b..cf4bccc1124 100644 --- a/src/libutil/windows/file-descriptor.cc +++ b/src/libutil/windows/file-descriptor.cc @@ -2,7 +2,6 @@ #include "nix/util/signals.hh" #include "nix/util/finally.hh" #include "nix/util/serialise.hh" -#include "nix/util/windows-error.hh" #include "nix/util/file-path.hh" #include diff --git a/src/libutil/windows/file-system.cc b/src/libutil/windows/file-system.cc index 79931d5914d..eb7e12fc9d8 100644 --- a/src/libutil/windows/file-system.cc +++ b/src/libutil/windows/file-system.cc @@ -1,5 +1,4 @@ #include "nix/util/file-system.hh" -#include "nix/util/windows-error.hh" #include "nix/util/logging.hh" namespace nix { @@ -24,10 +23,22 @@ Descriptor openDirectory(const std::filesystem::path & path) path.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, + /*lpSecurityAttributes=*/nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, - NULL); + /*hTemplateFile=*/nullptr); +} + +Descriptor openFileReadonly(const std::filesystem::path & path) +{ + return CreateFileW( + path.c_str(), + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_DELETE, + /*lpSecurityAttributes=*/nullptr, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + /*hTemplateFile=*/nullptr); } std::filesystem::path defaultTempDir() diff --git a/src/libutil/windows/include/nix/util/meson.build b/src/libutil/windows/include/nix/util/meson.build index 1bd56c4bd17..08285c3b9bd 100644 --- a/src/libutil/windows/include/nix/util/meson.build +++ b/src/libutil/windows/include/nix/util/meson.build @@ -5,5 +5,4 @@ include_dirs += include_directories('../..') headers += files( 'signals-impl.hh', 'windows-async-pipe.hh', - 'windows-error.hh', ) diff --git a/src/libutil/windows/include/nix/util/windows-error.hh b/src/libutil/windows/include/nix/util/windows-error.hh deleted file mode 100644 index a45425ad435..00000000000 --- a/src/libutil/windows/include/nix/util/windows-error.hh +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once -///@file - -#ifdef _WIN32 -# include - -# include "nix/util/error.hh" - -namespace nix::windows { - -/** - * Windows Error type. - * - * Unless you need to catch a specific error number, don't catch this in - * portable code. Catch `SystemError` instead. - */ -class WinError : public SystemError -{ -public: - DWORD lastError; - - /** - * Construct using the explicitly-provided error number. - * `FormatMessageA` will be used to try to add additional - * information to the message. - */ - template - WinError(DWORD lastError, const Args &... args) - : SystemError("") - , lastError(lastError) - { - auto hf = HintFmt(args...); - err.msg = HintFmt("%1%: %2%", Uncolored(hf.str()), renderError(lastError)); - } - - /** - * Construct using `GetLastError()` and the ambient "last error". - * - * Be sure to not perform another last-error-modifying operation - * before calling this constructor! - */ - template - WinError(const Args &... args) - : WinError(GetLastError(), args...) - { - } - -private: - - std::string renderError(DWORD lastError); -}; - -} // namespace nix::windows -#endif diff --git a/src/libutil/windows/muxable-pipe.cc b/src/libutil/windows/muxable-pipe.cc index b2eff70e611..f258f0f414b 100644 --- a/src/libutil/windows/muxable-pipe.cc +++ b/src/libutil/windows/muxable-pipe.cc @@ -1,6 +1,5 @@ #ifdef _WIN32 # include -# include "nix/util/windows-error.hh" # include "nix/util/logging.hh" # include "nix/util/util.hh" diff --git a/src/libutil/windows/processes.cc b/src/libutil/windows/processes.cc index f8f2900e55d..597be27f0a3 100644 --- a/src/libutil/windows/processes.cc +++ b/src/libutil/windows/processes.cc @@ -10,7 +10,6 @@ #include "nix/util/serialise.hh" #include "nix/util/file-system.hh" #include "nix/util/util.hh" -#include "nix/util/windows-error.hh" #include #include diff --git a/src/libutil/windows/users.cc b/src/libutil/windows/users.cc index eb92e7ab6ae..36392ff5006 100644 --- a/src/libutil/windows/users.cc +++ b/src/libutil/windows/users.cc @@ -2,7 +2,6 @@ #include "nix/util/users.hh" #include "nix/util/environment-variables.hh" #include "nix/util/file-system.hh" -#include "nix/util/windows-error.hh" #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN diff --git a/src/libutil/windows/windows-async-pipe.cc b/src/libutil/windows/windows-async-pipe.cc index f6a82a13975..09b72277a91 100644 --- a/src/libutil/windows/windows-async-pipe.cc +++ b/src/libutil/windows/windows-async-pipe.cc @@ -2,7 +2,6 @@ #ifdef _WIN32 # include "nix/util/windows-async-pipe.hh" -# include "nix/util/windows-error.hh" namespace nix::windows { diff --git a/src/libutil/windows/windows-error.cc b/src/libutil/windows/windows-error.cc index dd731dce22d..f04b70a2161 100644 --- a/src/libutil/windows/windows-error.cc +++ b/src/libutil/windows/windows-error.cc @@ -1,5 +1,7 @@ #ifdef _WIN32 -# include "nix/util/windows-error.hh" + +# include "nix/util/error.hh" + # include # define WIN32_LEAN_AND_MEAN # include