From 5d83eb9226c0ce608ec284d8c9bc22ce84a00c25 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 13 Nov 2017 10:52:36 +0100 Subject: [PATCH] gpg-agent: Avoid getting stuck in shutdown pending state. * agent/gpg-agent.c (handle_connections): Always check inotify fds. -- I noticed a gpg-agent processed, probably in shutdown_pending state, which was selecting on only these two inotify fds. The select returned immediately but because we did not handle the fds in shutdown_pending state they were not read and the next select call returned one of them immediately again. Actually that should not hanppen because the if (active_connections == 0) break; /* ready */ should have terminated the loop. For unknown reasons (maybe be just a connection thread terminated in a gdb session) that did not happen. By moving the check outside of the shutdown_pending condition and closing the fd after they have been triggered the code should be more robust. Signed-off-by: Werner Koch --- agent/gpg-agent.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 2e19d19c1..0b2b98212 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -3000,27 +3000,34 @@ handle_connections (gnupg_fd_t listen_fd, next timeout. */ continue; + /* The inotify fds are set even when a shutdown is pending (see + * above). So we must handle them in any case. To avoid that + * they trigger a second time we close them immediately. */ + if (sock_inotify_fd != -1 + && FD_ISSET (sock_inotify_fd, &read_fdset) + && gnupg_inotify_has_name (sock_inotify_fd, GPG_AGENT_SOCK_NAME)) + { + shutdown_pending = 1; + close (sock_inotify_fd); + sock_inotify_fd = -1; + log_info ("socket file has been removed - shutting down\n"); + } + + if (home_inotify_fd != -1 + && FD_ISSET (home_inotify_fd, &read_fdset)) + { + shutdown_pending = 1; + close (home_inotify_fd); + home_inotify_fd = -1; + log_info ("homedir has been removed - shutting down\n"); + } + if (!shutdown_pending) { int idx; ctrl_t ctrl; npth_t thread; - if (sock_inotify_fd != -1 - && FD_ISSET (sock_inotify_fd, &read_fdset) - && gnupg_inotify_has_name (sock_inotify_fd, GPG_AGENT_SOCK_NAME)) - { - shutdown_pending = 1; - log_info ("socket file has been removed - shutting down\n"); - } - - if (home_inotify_fd != -1 - && FD_ISSET (home_inotify_fd, &read_fdset)) - { - shutdown_pending = 1; - log_info ("homedir has been removed - shutting down\n"); - } - for (idx=0; idx < DIM(listentbl); idx++) { if (listentbl[idx].l_fd == GNUPG_INVALID_FD)