From 3ee839cc5ed4ed107882c203e378ec9e22e1d7a8 Mon Sep 17 00:00:00 2001 From: Alois Wohlschlager Date: Sat, 20 Sep 2025 11:24:46 +0200 Subject: [PATCH] libutil,nix: fix clashes with stdio stream identifiers The stdio stream identifiers (stdin, stdout, stderr) are allowed to be macros. In musl libc they are, for example doing `#define stdout (stdout)`, breaking compilation with an error when one of the clashing variables is attempted to be initialized the "wrong" way: ../lix/libutil/processes.cc:272:7: error: expected class member or base class name 272 | , stdout(stdout ? std::make_unique(std::move(stdout)) : nullptr) | ^ /nix/store/ziw42d7rvgnf3vkbfc8kry07kipwf1xm-musl-static-x86_64-unknown-linux-musl-1.2.5-dev/include/stdio.h:67:16: note: expanded from macro 'stdout' 67 | #define stdout (stdout) | ^ Other places only cause warnings on musl: ../lix/libutil/processes.cc:254:17: warning: parentheses were disambiguated as redundant parentheses around declaration of variable named 'stdout' [-Wvexing-parse] 254 | std::string stdout; | ^~~~~~ /nix/store/ziw42d7rvgnf3vkbfc8kry07kipwf1xm-musl-static-x86_64-unknown-linux-musl-1.2.5-dev/include/stdio.h:67:16: note: expanded from macro 'stdout' 67 | #define stdout (stdout) | ^~~~~~~~ ../lix/libutil/processes.cc:254:17: note: add a variable name to declare a 'std::string' (aka 'basic_string') initialized with 'stdout' 254 | std::string stdout; | ^ | varname /nix/store/ziw42d7rvgnf3vkbfc8kry07kipwf1xm-musl-static-x86_64-unknown-linux-musl-1.2.5-dev/include/stdio.h:67:16: note: expanded from macro 'stdout' 67 | #define stdout (stdout) | ^ ../lix/libutil/processes.cc:254:5: note: add enclosing parentheses to perform a function-style cast 254 | std::string stdout; | ^ | ( ) ../lix/libutil/processes.cc:254:17: note: remove parentheses to silence this warning 254 | std::string stdout; | ^ /nix/store/ziw42d7rvgnf3vkbfc8kry07kipwf1xm-musl-static-x86_64-unknown-linux-musl-1.2.5-dev/include/stdio.h:67:16: note: expanded from macro 'stdout' 67 | #define stdout (stdout) | ^ However they are still wrong, since the macro could be more complicated. Fix them as well. Change-Id: I6a6a6964a50ef7dec8f05f0bd8fc8f13f3036d51 --- lix/libutil/processes.cc | 12 ++++++------ lix/libutil/processes.hh | 8 ++++---- lix/nix/daemon.cc | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lix/libutil/processes.cc b/lix/libutil/processes.cc index 997c00b5b..1809a3019 100644 --- a/lix/libutil/processes.cc +++ b/lix/libutil/processes.cc @@ -251,25 +251,25 @@ try { options.captureStdout = true; int status = 0; - std::string stdout; + std::string childStdout; try { auto proc = runProgram2(options); Finally const _wait([&] { proc.waitAndCheck(); }); - stdout = TRY_AWAIT(proc.getStdout()->drain()); + childStdout = TRY_AWAIT(proc.getStdout()->drain()); } catch (ExecError & e) { status = e.status; } - co_return {status, std::move(stdout)}; + co_return {status, std::move(childStdout)}; } catch (...) { co_return result::current_exception(); } -RunningProgram::RunningProgram(PathView program, Pid pid, AutoCloseFD stdout) +RunningProgram::RunningProgram(PathView program, Pid pid, AutoCloseFD childStdout) : program(program) , pid(std::move(pid)) - , stdout(stdout ? std::make_unique(std::move(stdout)) : nullptr) + , childStdout(childStdout ? std::make_unique(std::move(childStdout)) : nullptr) { } @@ -286,7 +286,7 @@ RunningProgram::~RunningProgram() std::tuple> RunningProgram::release() { - return {pid.release(), std::move(stdout)}; + return {pid.release(), std::move(childStdout)}; } int RunningProgram::kill() diff --git a/lix/libutil/processes.hh b/lix/libutil/processes.hh index 67d067be0..7a5fae3d8 100644 --- a/lix/libutil/processes.hh +++ b/lix/libutil/processes.hh @@ -109,9 +109,9 @@ struct [[nodiscard("you must call RunningProgram::wait()")]] RunningProgram private: Path program; Pid pid; - std::unique_ptr stdout; + std::unique_ptr childStdout; - RunningProgram(PathView program, Pid pid, AutoCloseFD stdout); + RunningProgram(PathView program, Pid pid, AutoCloseFD childStdout); public: RunningProgram() = default; @@ -130,12 +130,12 @@ public: std::optional getStdoutFD() const { - return stdout ? std::optional(stdout->getFD()) : std::nullopt; + return childStdout ? std::optional(childStdout->getFD()) : std::nullopt; } AsyncFdIoStream * getStdout() const { - return stdout.get(); + return childStdout.get(); }; }; diff --git a/lix/nix/daemon.cc b/lix/nix/daemon.cc index c3cd842b4..fc3ebe528 100644 --- a/lix/nix/daemon.cc +++ b/lix/nix/daemon.cc @@ -458,16 +458,16 @@ static void forwardStdioConnection(AsyncIoRoot & aio, RemoteStore & store) { auto conn = store.openConnectionWrapper(); auto connSocket = AIO().lowLevelProvider.wrapSocketFd(conn->getFD()); - auto stdin = AIO().lowLevelProvider.wrapInputFd(STDIN_FILENO); - auto stdout = AIO().lowLevelProvider.wrapOutputFd(STDOUT_FILENO); + auto asyncStdin = AIO().lowLevelProvider.wrapInputFd(STDIN_FILENO); + auto asyncStdout = AIO().lowLevelProvider.wrapOutputFd(STDOUT_FILENO); - aio.blockOn(connSocket->pumpTo(*stdout) + aio.blockOn(connSocket->pumpTo(*asyncStdout) .then([](auto) -> Result { return { std::make_exception_ptr(EndOfFile("unexpected EOF from daemon socket")) }; }) - .exclusiveJoin(stdin->pumpTo(*connSocket).then([](auto) -> Result { + .exclusiveJoin(asyncStdin->pumpTo(*connSocket).then([](auto) -> Result { return result::success(); }))); }