diff options
author | Lennart Poettering <lennart@poettering.net> | 2011-02-13 17:09:29 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2011-02-13 17:09:29 +0100 |
commit | 060ed82ec24d942c5f519e3dae45e9e2bfb227d8 (patch) | |
tree | 75ab03e0474dd4cb844a4b61af17ae1573651f0a | |
parent | 46a08e381589c50394d71e428c09857dfeaa3761 (diff) |
systemctl: don't unnecessarily close stdin/stdout/stderr for tty agent so that locking by tty works
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | src/systemctl.c | 43 |
2 files changed, 24 insertions, 21 deletions
@@ -11,8 +11,6 @@ Features: * perhaps add "systemctl reenable" as combination of "systemctl disable" and "systemctl enable" -* tty name lock for password agent is broken, since it will always lock "/dev/tty" since we now reattach the agent process when forking it off systemctl - * need a way to apply mount options of api vfs from systemd unit files instead of fstab * udisks should not use udisks-part-id, instead use blkid. also not probe /dev/loopxxx diff --git a/src/systemctl.c b/src/systemctl.c index c09b31d1df..94a12ddeb2 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -121,7 +121,7 @@ static bool on_tty(void) { /* Note that this is invoked relatively early, before we start * the pager. That means the value we return reflects whether * we originally were started on a tty, not if we currently - * are. But this is intended, since we want color, and so on + * are. But this is intended, since we want colour and so on * when run in our own pager. */ if (_unlikely_(t < 0)) @@ -174,27 +174,32 @@ static void spawn_ask_password_agent(void) { /* Don't leak fds to the agent */ close_all_fds(NULL, 0); - /* Detach from stdin/stdout/stderr. and reopen - * /dev/tty for them. This is important to ensure that - * when systemctl is started via popen() or a similar - * call that expects to read EOF we actually do - * generate EOF and not delay this indefinitely by - * because we keep an unused copy of stdin around. */ - if ((fd = open("/dev/tty", O_RDWR)) < 0) { - log_error("Failed to open /dev/tty: %m"); - _exit(EXIT_FAILURE); - } + if (!isatty(STDOUT_FILENO) || !isatty(STDERR_FILENO)) { + /* Detach from stdout/stderr. and reopen + * /dev/tty for them. This is important to + * ensure that when systemctl is started via + * popen() or a similar call that expects to + * read EOF we actually do generate EOF and + * not delay this indefinitely by because we + * keep an unused copy of stdin around. */ + if ((fd = open("/dev/tty", O_WRONLY)) < 0) { + log_error("Failed to open /dev/tty: %m"); + _exit(EXIT_FAILURE); + } - close(STDIN_FILENO); - close(STDOUT_FILENO); - close(STDERR_FILENO); + if (!isatty(STDOUT_FILENO)) { + close(STDOUT_FILENO); + dup2(fd, STDOUT_FILENO); + } - dup2(fd, STDIN_FILENO); - dup2(fd, STDOUT_FILENO); - dup2(fd, STDERR_FILENO); + if (!isatty(STDERR_FILENO)) { + close(STDERR_FILENO); + dup2(fd, STDERR_FILENO); + } - if (fd > 2) - close(fd); + if (fd > 2) + close(fd); + } execv(args[0], (char **) args); _exit(EXIT_FAILURE); |