diff options
author | Stef Walter <stefw@gnome.org> | 2014-03-14 11:05:21 +0100 |
---|---|---|
committer | Stef Walter <stefw@gnome.org> | 2014-03-14 11:29:25 +0100 |
commit | 61cc045d145e2211a5d4993b9f1f29f548a0177e (patch) | |
tree | 0ea5e58458309da6363107206a0e67c2a6637baa /pam/gkr-pam-client.c | |
parent | 90a3ae6656960b36a1d2277f336222bd49d5eece (diff) | |
download | gnome-keyring-61cc045d145e2211a5d4993b9f1f29f548a0177e.tar.gz |
daemon: Provide caller syncronization for quitting the daemon
Quit control messages are a bit strange because the daemon will quit
shortly afterwards. There are three syncronization issues here.
1. We need the response to be written right away, because if
we wait for the main loop it might not be written.
2. Callers may want to wait for the daemon to exit, so keep the
socket open until we do.
3. Prevent additional connections on the control socket.
Diffstat (limited to 'pam/gkr-pam-client.c')
-rw-r--r-- | pam/gkr-pam-client.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/pam/gkr-pam-client.c b/pam/gkr-pam-client.c index 5c92cec5..ee175474 100644 --- a/pam/gkr-pam-client.c +++ b/pam/gkr-pam-client.c @@ -265,7 +265,10 @@ write_part (int fd, const unsigned char *data, int len, int *res) } static int -read_part (int fd, unsigned char *data, int len) +read_part (int fd, + unsigned char *data, + int len, + int disconnect_ok) { int r, all; @@ -275,11 +278,15 @@ read_part (int fd, unsigned char *data, int len) if (r < 0) { if (errno == EAGAIN) continue; + if (errno == ECONNRESET && disconnect_ok) + return 0; syslog (GKR_LOG_ERR, "couldn't read data from gnome-keyring-daemon: %s", strerror (errno)); return -1; } - if (r == 0) { + if (r == 0) { + if (disconnect_ok) + return 0; syslog (GKR_LOG_ERR, "couldn't read data from gnome-keyring-daemon: %s", "unexpected end of data"); return -1; @@ -300,6 +307,7 @@ keyring_daemon_op (struct sockaddr_un *addr, { int ret = GKD_CONTROL_RESULT_OK; unsigned char buf[4]; + int want_disconnect; int i, sock = -1; uint oplen, l; @@ -343,9 +351,14 @@ keyring_daemon_op (struct sockaddr_un *addr, if (ret != GKD_CONTROL_RESULT_OK) goto done; - + /* + * If we're asking the daemon to quit, then we expect + * disconnects after we send the initial request + */ + want_disconnect = (op == GKD_CONTROL_OP_QUIT); + /* Read the response length */ - if (read_part (sock, buf, 4) != 4) { + if (read_part (sock, buf, 4, want_disconnect) != 4) { ret = GKD_CONTROL_RESULT_FAILED; goto done; } @@ -358,12 +371,20 @@ keyring_daemon_op (struct sockaddr_un *addr, goto done; } - if (read_part (sock, buf, 4) != 4) { + if (read_part (sock, buf, 4, want_disconnect) != 4) { ret = GKD_CONTROL_RESULT_FAILED; goto done; } ret = egg_buffer_decode_uint32 (buf); - + + /* + * If we asked the daemon to quit, wait for it to disconnect + * by waiting until the socket disconnects from the other end. + */ + if (want_disconnect) { + while (read (sock, buf, 4) > 0); + } + done: if (sock >= 0) close (sock); |