mirror of
https://github.com/mpv-player/mpv
synced 2024-12-26 17:12:36 +00:00
e0b4daf3ad
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.
92 lines
2.1 KiB
C
92 lines
2.1 KiB
C
#include <pthread.h>
|
|
#include <stdio.h>
|
|
#include <windows.h>
|
|
#include <io.h>
|
|
|
|
#include <stdint.h>
|
|
#include <waio/waio.h>
|
|
|
|
#include "common/msg.h"
|
|
#include "osdep/io.h"
|
|
#include "input.h"
|
|
|
|
static void request_cancel(struct mp_input_src *src)
|
|
{
|
|
HANDLE terminate = src->priv;
|
|
|
|
MP_VERBOSE(src, "Exiting...\n");
|
|
SetEvent(terminate);
|
|
}
|
|
|
|
static void uninit(struct mp_input_src *src)
|
|
{
|
|
HANDLE terminate = src->priv;
|
|
|
|
CloseHandle(terminate);
|
|
MP_VERBOSE(src, "Exited.\n");
|
|
}
|
|
|
|
static void read_pipe_thread(struct mp_input_src *src, void *param)
|
|
{
|
|
char *filename = talloc_strdup(src, param);
|
|
|
|
struct waio_cx_interface *waio = NULL;
|
|
int mode = O_RDONLY;
|
|
int fd = -1;
|
|
bool close_fd = true;
|
|
if (strcmp(filename, "/dev/stdin") == 0) { // for symmetry with unix
|
|
fd = STDIN_FILENO;
|
|
close_fd = false;
|
|
}
|
|
if (fd < 0)
|
|
fd = open(filename, mode);
|
|
if (fd < 0) {
|
|
MP_ERR(src, "Can't open %s.\n", filename);
|
|
goto done;
|
|
}
|
|
|
|
waio = waio_alloc((void *)_get_osfhandle(fd), 0, NULL, NULL);
|
|
if (!waio) {
|
|
MP_ERR(src, "Can't initialize win32 file reader.\n");
|
|
goto done;
|
|
}
|
|
|
|
HANDLE terminate = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
if (!terminate)
|
|
goto done;
|
|
|
|
src->priv = terminate;
|
|
src->cancel = request_cancel;
|
|
src->uninit = uninit;
|
|
mp_input_src_init_done(src);
|
|
|
|
char buffer[128];
|
|
struct waio_aiocb cb = {
|
|
.aio_buf = buffer,
|
|
.aio_nbytes = sizeof(buffer),
|
|
.hsignal = terminate,
|
|
};
|
|
while (1) {
|
|
if (waio_read(waio, &cb)) {
|
|
MP_ERR(src, "Read operation failed.\n");
|
|
break;
|
|
}
|
|
if (waio_suspend(waio, (const struct waio_aiocb *[]){&cb}, 1, NULL))
|
|
break;
|
|
ssize_t r = waio_return(waio, &cb);
|
|
if (r <= 0)
|
|
break; // EOF or error
|
|
mp_input_src_feed_cmd_text(src, buffer, r);
|
|
}
|
|
|
|
done:
|
|
waio_free(waio);
|
|
if (close_fd)
|
|
close(fd);
|
|
}
|
|
|
|
void mp_input_pipe_add(struct input_ctx *ictx, const char *filename)
|
|
{
|
|
mp_input_add_thread_src(ictx, (void *)filename, read_pipe_thread);
|
|
}
|