]> code.delx.au - pulseaudio/commitdiff
pacmd: port pacmd from select() to poll() so that we notice writer side hangups
authorLennart Poettering <lennart@poettering.net>
Wed, 12 Aug 2009 19:42:02 +0000 (21:42 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 12 Aug 2009 19:42:02 +0000 (21:42 +0200)
src/utils/pacmd.c

index ac60a0bcd80876051b09047d6492eed88b2b40b0..e4d054b8d594d88795010b64a117a0149944e286 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <assert.h>
 #include <signal.h>
-#include <sys/select.h>
+#include <sys/poll.h>
 #include <sys/socket.h>
 #include <unistd.h>
 #include <errno.h>
 
 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;
         }
     }