From: Daan De Meyer Date: Wed, 20 May 2026 12:14:52 +0000 (+0000) Subject: ptyfwd: Imply PTY_FORWARD_READ_ONLY if stdin isn't readable X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=12836f982a29215ee0fa1a608ec7935c7ee903c4;p=thirdparty%2Fsystemd.git ptyfwd: Imply PTY_FORWARD_READ_ONLY if stdin isn't readable if stdin is connected to a closed pipe or similar, imply PTY_FORWARD_READ_ONLY so we don't even try to read from it in the first place. Otherwise we'll immediately get a hangup which will cause the forwarder to call sd_event_exit() and shut down the event loop. Debugged-by: Christian Brauner --- diff --git a/src/shared/ptyfwd.c b/src/shared/ptyfwd.c index 88cfd596d05..fcc1500dc5c 100644 --- a/src/shared/ptyfwd.c +++ b/src/shared/ptyfwd.c @@ -934,6 +934,24 @@ int pty_forward_new( assert(master >= 0); assert(ret); + if (!FLAGS_SET(flags, PTY_FORWARD_READ_ONLY)) { + /* If stdin isn't actually opened for reading, or refers to the read end of a pipe (or + * socket) whose peer has already hung up, then there's nothing for us to forward — imply + * read-only mode. */ + r = RET_NERRNO(fcntl(STDIN_FILENO, F_GETFL)); + if (r < 0 && r != -EBADF) + return log_debug_errno(errno, "Failed to query stdin flags: %m"); + if (r == -EBADF || (r & O_ACCMODE_STRICT) == O_WRONLY) + flags |= PTY_FORWARD_READ_ONLY; + else { + r = pipe_eof(STDIN_FILENO); + if (r < 0) + log_debug_errno(r, "Failed to check whether stdin is at EOF, ignoring: %m"); + else if (r > 0) + flags |= PTY_FORWARD_READ_ONLY; + } + } + f = new(PTYForward, 1); if (!f) return -ENOMEM;