summaryrefslogtreecommitdiffstats
path: root/src/utils/pacmd.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2009-08-12 21:42:02 +0200
committerLennart Poettering <lennart@poettering.net>2009-08-12 21:42:02 +0200
commit5fcb8a3c0838a4ecdb00a0af09b6e1a358b114d0 (patch)
tree772196c910e692bb9dbeee5bdda66a407b275e8a /src/utils/pacmd.c
parent286ab2f19370c7a0041897435614b2c6aadc8e70 (diff)
pacmd: port pacmd from select() to poll() so that we notice writer side hangups
Diffstat (limited to 'src/utils/pacmd.c')
-rw-r--r--src/utils/pacmd.c60
1 files changed, 40 insertions, 20 deletions
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 <assert.h>
#include <signal.h>
-#include <sys/select.h>
+#include <sys/poll.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
@@ -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;
}
}