Skip to content

Commit

Permalink
spawn/IProtocol: add commands for copying stdin to stdout/stderr
Browse files Browse the repository at this point in the history
This reduces some overhead and fixes an assertion failure that can
occur when "tty" is set because previously, stdin/stdout fds were not
the same if they had been transferred through a local socket.
  • Loading branch information
MaxKellermann committed Oct 22, 2023
1 parent 138b226 commit adf620b
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 2 deletions.
17 changes: 15 additions & 2 deletions src/spawn/Client.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,21 @@ Serialize(SpawnSerializer &s, const PreparedChildProcess &p)
}

s.CheckWriteFd(SpawnExecCommand::STDIN, p.stdin_fd);
s.CheckWriteFd(SpawnExecCommand::STDOUT, p.stdout_fd);
s.CheckWriteFd(SpawnExecCommand::STDERR, p.stderr_fd);

if (p.stdout_fd.IsDefined()) {
if (p.stdout_fd == p.stdin_fd)
s.Write(SpawnExecCommand::STDOUT_IS_STDIN);
else
s.WriteFd(SpawnExecCommand::STDOUT, p.stdout_fd);
}

if (p.stderr_fd.IsDefined()) {
if (p.stderr_fd == p.stdin_fd)
s.Write(SpawnExecCommand::STDERR_IS_STDIN);
else
s.WriteFd(SpawnExecCommand::STDERR, p.stderr_fd);
}

s.CheckWriteFd(SpawnExecCommand::CONTROL, p.control_fd);

s.CheckWriteFd(SpawnExecCommand::RETURN_STDERR,
Expand Down
2 changes: 2 additions & 0 deletions src/spawn/IProtocol.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ enum class SpawnExecCommand : uint8_t {
UMASK,
STDIN,
STDOUT,
STDOUT_IS_STDIN,
STDERR,
STDERR_IS_STDIN,
STDERR_PATH,
RETURN_STDERR,
RETURN_PIDFD,
Expand Down
8 changes: 8 additions & 0 deletions src/spawn/Server.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -542,10 +542,18 @@ SpawnServerConnection::HandleExecMessage(SpawnPayload payload,
p.SetStdout(fds.Get().Steal());
break;

case SpawnExecCommand::STDOUT_IS_STDIN:
p.stdout_fd = p.stdin_fd;
break;

case SpawnExecCommand::STDERR:
p.SetStderr(fds.Get().Steal());
break;

case SpawnExecCommand::STDERR_IS_STDIN:
p.stderr_fd = p.stdin_fd;
break;

case SpawnExecCommand::STDERR_PATH:
p.stderr_path = payload.ReadString();
break;
Expand Down

0 comments on commit adf620b

Please sign in to comment.