From f2432be62d6d619c979bdfa7f43bdb9abe367581 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Mon, 19 Jan 2026 19:28:46 +0100 Subject: [PATCH] libstore: use runProgram2 for ssh connections we do not need explict redirection management now, and dieWithParent doesn't need an override either. we'd much prefer to kill ssh if the process in charge exits; even ssh multiplexers are not fazed by this Change-Id: I81e28b7605df73c887878ea4716228c7ad0f5c6f --- lix/libstore/ssh.cc | 43 +++++++++++++++---------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/lix/libstore/ssh.cc b/lix/libstore/ssh.cc index b93b3cff2..cb9970b3c 100644 --- a/lix/libstore/ssh.cc +++ b/lix/libstore/ssh.cc @@ -6,6 +6,7 @@ #include "lix/libutil/file-descriptor.hh" #include "lix/libutil/finally.hh" #include "lix/libutil/logging.hh" +#include "lix/libutil/processes.hh" #include "lix/libutil/strings.hh" #include "lix/libstore/temporary-dir.hh" #include @@ -54,8 +55,6 @@ std::unique_ptr SSH::startCommand(const std::string & command) { auto [parent, child] = SocketPair::stream(); auto conn = std::make_unique(); - ProcessOptions options; - options.dieWithParent = false; std::optional>> resumeLoggerDefer; if (!fakeSSH) { @@ -63,41 +62,29 @@ std::unique_ptr SSH::startCommand(const std::string & command) resumeLoggerDefer.emplace([&]() { logger->resume(); }); } - Strings args; + RunOptions options; // We specifically spawn bash here, to (hopefully) get // reasonably POSIX-y semantics for the things we're about // to do next. if (fakeSSH) { - args = {"bash", "-c", command}; + options.program = "bash"; + options.args = {"-c", command}; } else { - args = {"ssh", host.c_str(), "-x", "-T"}; - addCommonSSHOpts(args); - args.push_back(command); + options.program = "ssh"; + options.args = {host.c_str(), "-x", "-T"}; + addCommonSSHOpts(options.args); + options.args.push_back(command); } - printMsg(lvlChatty, "running ssh: %s", concatMapStringsSep(" ", args, shellEscape)); + options.redirections.push_back({.dup = STDIN_FILENO, .from = child.get()}); + options.redirections.push_back({.dup = STDOUT_FILENO, .from = child.get()}); + if (logFD != -1) { + options.redirections.push_back({.dup = STDERR_FILENO, .from = logFD}); + } - conn->sshPid = startProcess([&]() { - restoreProcessContext(); - - parent.close(); - - if (dup2(child.get(), STDIN_FILENO) == -1) { - throw SysError("duping over stdin"); - } - if (dup2(child.get(), STDOUT_FILENO) == -1) { - throw SysError("duping over stdout"); - } - if (logFD != -1 && dup2(logFD, STDERR_FILENO) == -1) { - throw SysError("duping over stderr"); - } - - sys::execvp(*args.begin(), args); - - // could not exec ssh/bash - throw SysError("unable to execute '%s'", args.front()); - }, options); + auto [pid, _stdout] = runProgram2(options).release(); + conn->sshPid = std::move(pid); child.close();