summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2011-02-13 17:09:29 +0100
committerLennart Poettering <lennart@poettering.net>2011-02-13 17:09:29 +0100
commit060ed82ec24d942c5f519e3dae45e9e2bfb227d8 (patch)
tree75ab03e0474dd4cb844a4b61af17ae1573651f0a
parent46a08e381589c50394d71e428c09857dfeaa3761 (diff)
systemctl: don't unnecessarily close stdin/stdout/stderr for tty agent so that locking by tty works
-rw-r--r--TODO2
-rw-r--r--src/systemctl.c43
2 files changed, 24 insertions, 21 deletions
diff --git a/TODO b/TODO
index 747a66978a..8660f16f9c 100644
--- a/TODO
+++ b/TODO
@@ -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);