From 5fcb8a3c0838a4ecdb00a0af09b6e1a358b114d0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 12 Aug 2009 21:42:02 +0200 Subject: pacmd: port pacmd from select() to poll() so that we notice writer side hangups --- src/utils/pacmd.c | 60 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 20 deletions(-) (limited to 'src/utils/pacmd.c') diff --git a/src/utils/pacmd.c b/src/utils/pacmd.c index ac60a0bc..e4d054b8 100644 --- a/src/utils/pacmd.c +++ b/src/utils/pacmd.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include @@ -45,6 +45,13 @@ int main(int argc, char*argv[]) { + enum { + WATCH_STDIN, + WATCH_STDOUT, + WATCH_SOCKET, + N_WATCH + }; + pid_t pid ; int fd = -1; int ret = 1, i; @@ -53,6 +60,7 @@ int main(int argc, char*argv[]) { size_t ibuf_index, ibuf_length, obuf_index, obuf_length; char *cli; pa_bool_t ibuf_eof, obuf_eof, ibuf_closed, obuf_closed; + struct pollfd pollfd[N_WATCH]; setlocale(LC_ALL, ""); bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); @@ -120,38 +128,45 @@ int main(int argc, char*argv[]) { ibuf_eof = TRUE; } - for (;;) { - fd_set ifds, ofds; + pa_zero(pollfd); + pollfd[WATCH_STDIN].fd = STDIN_FILENO; + pollfd[WATCH_STDOUT].fd = STDOUT_FILENO; + pollfd[WATCH_SOCKET].fd = fd; + + for (;;) { if (ibuf_eof && obuf_eof && ibuf_length <= 0 && obuf_length <= 0) break; - FD_ZERO(&ifds); - FD_ZERO(&ofds); + pollfd[WATCH_STDIN].events = pollfd[WATCH_STDOUT].events = pollfd[WATCH_SOCKET].events = 0; if (obuf_length > 0) - FD_SET(1, &ofds); + pollfd[WATCH_STDOUT].events |= POLLOUT; else if (!obuf_eof) - FD_SET(fd, &ifds); + pollfd[WATCH_SOCKET].events |= POLLIN; if (ibuf_length > 0) - FD_SET(fd, &ofds); + pollfd[WATCH_SOCKET].events |= POLLOUT; else if (!ibuf_eof) - FD_SET(0, &ifds); + pollfd[WATCH_STDIN].events |= POLLIN; - if (select(FD_SETSIZE, &ifds, &ofds, NULL, NULL) < 0) { - pa_log(_("select(): %s"), strerror(errno)); + if (poll(pollfd, N_WATCH, -1) < 0) { + + if (errno == EINTR) + continue; + + pa_log(_("poll(): %s"), strerror(errno)); goto fail; } - if (FD_ISSET(0, &ifds)) { + if (pollfd[WATCH_STDIN].revents & POLLIN) { ssize_t r; pa_assert(!ibuf_length); - if ((r = pa_read(0, ibuf, sizeof(ibuf), NULL)) <= 0) { + if ((r = pa_read(STDIN_FILENO, ibuf, sizeof(ibuf), NULL)) <= 0) { if (r < 0) { pa_log(_("read(): %s"), strerror(errno)); goto fail; @@ -164,7 +179,7 @@ int main(int argc, char*argv[]) { } } - if (FD_ISSET(fd, &ifds)) { + if (pollfd[WATCH_SOCKET].revents & POLLIN) { ssize_t r; pa_assert(!obuf_length); @@ -181,21 +196,26 @@ int main(int argc, char*argv[]) { } } - if (FD_ISSET(1, &ofds)) { + if (pollfd[WATCH_STDOUT].revents & POLLHUP) { + obuf_eof = TRUE; + obuf_length = 0; + } else if (pollfd[WATCH_STDOUT].revents & POLLOUT) { ssize_t r; pa_assert(obuf_length); - if ((r = pa_write(1, obuf + obuf_index, obuf_length, NULL)) < 0) { + if ((r = pa_write(STDOUT_FILENO, obuf + obuf_index, obuf_length, NULL)) < 0) { pa_log(_("write(): %s"), strerror(errno)); goto fail; } obuf_length -= (size_t) r; obuf_index += obuf_index; - } - if (FD_ISSET(fd, &ofds)) { + if (pollfd[WATCH_SOCKET].revents & POLLHUP) { + ibuf_eof = TRUE; + ibuf_length = 0; + } if (pollfd[WATCH_SOCKET].revents & POLLOUT) { ssize_t r; pa_assert(ibuf_length); @@ -209,14 +229,14 @@ int main(int argc, char*argv[]) { } if (ibuf_length <= 0 && ibuf_eof && !ibuf_closed) { - pa_close(0); + pa_close(STDIN_FILENO); shutdown(fd, SHUT_WR); ibuf_closed = TRUE; } if (obuf_length <= 0 && obuf_eof && !obuf_closed) { shutdown(fd, SHUT_RD); - pa_close(1); + pa_close(STDOUT_FILENO); obuf_closed = TRUE; } } -- cgit