chiark / gitweb /
ask-password-tty: properly handle SIGINT/SIGTERM
authorLennart Poettering <lennart@poettering.net>
Tue, 26 Oct 2010 13:15:00 +0000 (15:15 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 26 Oct 2010 13:15:00 +0000 (15:15 +0200)
TODO
src/ask-password.c
src/tty-ask-password-agent.c

diff --git a/TODO b/TODO
index f1e6312..45ef095 100644 (file)
--- a/TODO
+++ b/TODO
@@ -49,8 +49,6 @@
 
 * suspend, resume
 
-* passphrase agent https://bugs.freedesktop.org/show_bug.cgi?id=30038
-
 * systemctl auto-pager a la git
 
 * merge CK
@@ -58,7 +56,7 @@
 * start getty 2-6 only when actual vt switch happens
   (same model as socket on-demand activation)
 
-* spawn ask-password tty agent temporarily in systemctl
+* ask-password: find way to disable wall agent where tty agent is running
 
 * readahead: btrfs/LVM SSD detection
 
index 493bbfe..1d89eaf 100644 (file)
@@ -167,14 +167,21 @@ static int parse_argv(int argc, char *argv[]) {
 }
 
 static int ask_agent(void) {
+        enum {
+                FD_SOCKET,
+                FD_SIGNAL,
+                _FD_MAX
+        };
+
         char temp[] = "/dev/.systemd/ask-password/tmp.XXXXXX";
         char final[sizeof(temp)] = "";
         int fd = -1, r;
         FILE *f = NULL;
         char *socket_name = NULL;
-        int socket_fd = -1, signal_fd;
+        int socket_fd = -1, signal_fd = -1;
         sigset_t mask;
         usec_t not_after;
+        struct pollfd pollfd[_FD_MAX];
 
         mkdir_p("/dev/.systemd/ask-password", 0755);
 
@@ -246,13 +253,13 @@ static int ask_agent(void) {
                 goto finish;
         }
 
-        for (;;) {
-                enum {
-                        FD_SOCKET,
-                        FD_SIGNAL,
-                        _FD_MAX
-                };
+        zero(pollfd);
+        pollfd[FD_SOCKET].fd = socket_fd;
+        pollfd[FD_SOCKET].events = POLLIN;
+        pollfd[FD_SIGNAL].fd = signal_fd;
+        pollfd[FD_SIGNAL].events = POLLIN;
 
+        for (;;) {
                 char passphrase[LINE_MAX+1];
                 struct msghdr msghdr;
                 struct iovec iovec;
@@ -262,16 +269,9 @@ static int ask_agent(void) {
                         uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
                 } control;
                 ssize_t n;
-                struct pollfd pollfd[_FD_MAX];
                 int k;
 
-                zero(pollfd);
-                pollfd[FD_SOCKET].fd = socket_fd;
-                pollfd[FD_SOCKET].events = POLLIN;
-                pollfd[FD_SIGNAL].fd = signal_fd;
-                pollfd[FD_SIGNAL].events = POLLIN;
-
-                if ((k = poll(pollfd, 2, arg_timeout/USEC_PER_MSEC)) < 0) {
+                if ((k = poll(pollfd, _FD_MAX, arg_timeout/USEC_PER_MSEC)) < 0) {
 
                         if (errno == EINTR)
                                 continue;
@@ -366,6 +366,9 @@ finish:
         if (socket_fd >= 0)
                 close_nointr_nofail(socket_fd);
 
+        if (signal_fd >= 0)
+                close_nointr_nofail(signal_fd);
+
         if (f)
                 fclose(f);
 
index 5b42939..d610cbd 100644 (file)
@@ -29,6 +29,7 @@
 #include <sys/inotify.h>
 #include <unistd.h>
 #include <getopt.h>
+#include <sys/signalfd.h>
 
 #include "util.h"
 #include "conf-parser.h"
@@ -385,8 +386,15 @@ finish:
 }
 
 static int watch_passwords(void) {
-        int notify;
-        struct pollfd pollfd;
+        enum {
+                FD_INOTIFY,
+                FD_SIGNAL,
+                _FD_MAX
+        };
+
+        int notify = -1, signal_fd = -1;
+        struct pollfd pollfd[_FD_MAX];
+        sigset_t mask;
         int r;
 
         mkdir_p("/dev/.systemd/ask-password", 0755);
@@ -401,15 +409,27 @@ static int watch_passwords(void) {
                 goto finish;
         }
 
+        assert_se(sigemptyset(&mask) == 0);
+        sigset_add_many(&mask, SIGINT, SIGTERM, -1);
+        assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
+
+        if ((signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) {
+                log_error("signalfd(): %m");
+                r = -errno;
+                goto finish;
+        }
+
         zero(pollfd);
-        pollfd.fd = notify;
-        pollfd.events = POLLIN;
+        pollfd[FD_INOTIFY].fd = notify;
+        pollfd[FD_INOTIFY].events = POLLIN;
+        pollfd[FD_SIGNAL].fd = signal_fd;
+        pollfd[FD_SIGNAL].events = POLLIN;
 
         for (;;) {
                 if ((r = show_passwords()) < 0)
                         break;
 
-                if (poll(&pollfd, 1, -1) < 0) {
+                if (poll(pollfd, _FD_MAX, -1) < 0) {
 
                         if (errno == EINTR)
                                 continue;
@@ -418,8 +438,11 @@ static int watch_passwords(void) {
                         goto finish;
                 }
 
-                if (pollfd.revents != 0)
+                if (pollfd[FD_INOTIFY].revents != 0)
                         flush_fd(notify);
+
+                if (pollfd[FD_SIGNAL].revents != 0)
+                        break;
         }
 
         r = 0;
@@ -428,6 +451,9 @@ finish:
         if (notify >= 0)
                 close_nointr_nofail(notify);
 
+        if (signal_fd >= 0)
+                close_nointr_nofail(signal_fd);
+
         return r;
 }