diff options
author | wm4 <wm4@nowhere> | 2014-09-14 16:21:04 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-09-14 16:24:01 +0200 |
commit | e0b4daf3ad240ecf70af73c13b6ca9b1062a507f (patch) | |
tree | e52d79650aa69c0288dd5d9c896ab943c692f88f /input/pipe-unix.c | |
parent | b44571ababeb368e94df6665c1d370d817a51135 (diff) | |
download | mpv-e0b4daf3ad240ecf70af73c13b6ca9b1062a507f.tar.bz2 mpv-e0b4daf3ad240ecf70af73c13b6ca9b1062a507f.tar.xz |
input: use libwaio for pipe input on Windows
Use libwaio to read from pipes (stdin or named pipes) on Windows. This
liberates us from nasty issues, such as pipes (as created by most
programs) not being possible to read in a non-blocking or event-driven
way. Although it would be possible to do that in a somewhat sane way
on Vista+, it's still not easy, and on XP it's especially hard. libwaio
handles these things for us.
Move pipe.c to pipe-unix.c, and remove Windows specific things. Also
adjust the input.c code to make this work cleanly.
Diffstat (limited to 'input/pipe-unix.c')
-rw-r--r-- | input/pipe-unix.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/input/pipe-unix.c b/input/pipe-unix.c new file mode 100644 index 0000000000..51eb315d6b --- /dev/null +++ b/input/pipe-unix.c @@ -0,0 +1,59 @@ +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +#include <poll.h> + +#include "common/msg.h" +#include "osdep/io.h" +#include "input.h" +#include "cmd_parse.h" + +static void read_pipe_thread(struct mp_input_src *src, void *param) +{ + void *tmp = talloc_new(NULL); + char *filename = talloc_strdup(tmp, param); // param deallocates after init + int wakeup_fd = mp_input_src_get_wakeup_fd(src); + int fd = -1; + + struct mp_log *log = src->log; + + int mode = O_RDONLY; + // Use RDWR for FIFOs to ensure they stay open over multiple accesses. + struct stat st; + if (stat(filename, &st) == 0 && S_ISFIFO(st.st_mode)) + mode = O_RDWR; + fd = open(filename, mode); + if (fd < 0) { + mp_err(log, "Can't open %s.\n", filename); + goto done; + } + + mp_input_src_init_done(src); + + while (1) { + struct pollfd fds[2] = { + { .fd = fd, .events = POLLIN }, + { .fd = wakeup_fd, .events = POLLIN }, + }; + poll(fds, 2, -1); + if (!(fds[0].revents & POLLIN)) + break; + char buffer[128]; + int r = read(fd, buffer, sizeof(buffer)); + if (r <= 0) + break; + mp_input_src_feed_cmd_text(src, buffer, r); + } + +done: + close(fd); + talloc_free(tmp); +} + +void mp_input_pipe_add(struct input_ctx *ictx, const char *filename) +{ + mp_input_add_thread_src(ictx, (void *)filename, read_pipe_thread); +} |