lua: subprocess: remove minor code duplication

Now that the code for stderr and stdout does exactly the same things,
and the specialization is in the callbacks, this is blatantly
duplicated.

Also, define a typedef for those callbacks to reduce the verbosity.
This commit is contained in:
wm4 2014-11-16 19:10:26 +01:00
parent 4cf1843664
commit f4804b0c45
1 changed files with 22 additions and 31 deletions

View File

@ -1168,6 +1168,8 @@ static int script_join_path(lua_State *L)
return 1; return 1;
} }
typedef void (*read_cb)(void *ctx, char *data, size_t size);
#ifdef __MINGW32__ #ifdef __MINGW32__
#include <windows.h> #include <windows.h>
#include "osdep/io.h" #include "osdep/io.h"
@ -1175,7 +1177,7 @@ static int script_join_path(lua_State *L)
struct subprocess_ctx { struct subprocess_ctx {
HANDLE stderr_read; HANDLE stderr_read;
void *cb_ctx; void *cb_ctx;
void (*on_stderr)(void *ctx, char *data, size_t size); read_cb on_stderr;
}; };
static void write_arg(bstr *cmdline, char *arg) static void write_arg(bstr *cmdline, char *arg)
@ -1260,9 +1262,7 @@ static void *stderr_routine(void *arg)
} }
static int subprocess(char **args, struct mp_cancel *cancel, void *ctx, static int subprocess(char **args, struct mp_cancel *cancel, void *ctx,
void (*on_stdout)(void *ctx, char *data, size_t size), read_cb on_stdout, read_cb on_stderr, char **error)
void (*on_stderr)(void *ctx, char *data, size_t size),
char **error)
{ {
wchar_t *tmp = talloc_new(NULL); wchar_t *tmp = talloc_new(NULL);
HANDLE stdout_read = NULL, stdout_write = NULL; HANDLE stdout_read = NULL, stdout_write = NULL;
@ -1380,9 +1380,7 @@ static int sparse_poll(struct pollfd *fds, int num_fds, int timeout)
} }
static int subprocess(char **args, struct mp_cancel *cancel, void *ctx, static int subprocess(char **args, struct mp_cancel *cancel, void *ctx,
void (*on_stdout)(void *ctx, char *data, size_t size), read_cb on_stdout, read_cb on_stderr, char **error)
void (*on_stderr)(void *ctx, char *data, size_t size),
char **error)
{ {
posix_spawn_file_actions_t fa; posix_spawn_file_actions_t fa;
bool fa_destroy = false; bool fa_destroy = false;
@ -1415,37 +1413,30 @@ static int subprocess(char **args, struct mp_cancel *cancel, void *ctx,
close(p_stderr[1]); close(p_stderr[1]);
p_stderr[1] = -1; p_stderr[1] = -1;
int *read_fds[2] = {&p_stdout[0], &p_stderr[0]};
read_cb read_cbs[2] = {on_stdout, on_stderr};
while (p_stdout[0] >= 0 || p_stderr[0] >= 0) { while (p_stdout[0] >= 0 || p_stderr[0] >= 0) {
struct pollfd fds[] = { struct pollfd fds[] = {
{.events = POLLIN, .fd = p_stdout[0]}, {.events = POLLIN, .fd = *read_fds[0]},
{.events = POLLIN, .fd = p_stderr[0]}, {.events = POLLIN, .fd = *read_fds[1]},
{.events = POLLIN, .fd = cancel ? mp_cancel_get_fd(cancel) : -1}, {.events = POLLIN, .fd = cancel ? mp_cancel_get_fd(cancel) : -1},
}; };
if (sparse_poll(fds, MP_ARRAY_SIZE(fds), -1) < 0 && errno != EINTR) if (sparse_poll(fds, MP_ARRAY_SIZE(fds), -1) < 0 && errno != EINTR)
break; break;
if (fds[0].revents) { for (int n = 0; n < 2; n++) {
if (fds[n].revents) {
char buf[4096]; char buf[4096];
ssize_t r = read(p_stdout[0], buf, sizeof(buf)); ssize_t r = read(*read_fds[n], buf, sizeof(buf));
if (r < 0 && errno == EINTR) if (r < 0 && errno == EINTR)
continue; continue;
if (r > 0) if (r > 0 && read_cbs[n])
on_stdout(ctx, buf, r); read_cbs[n](ctx, buf, r);
if (r <= 0) { if (r <= 0) {
close(p_stdout[0]); close(*read_fds[n]);
p_stdout[0] = -1; *read_fds[n] = -1;
} }
} }
if (fds[1].revents) {
char buf[4096];
ssize_t r = read(p_stderr[0], buf, sizeof(buf));
if (r < 0 && errno == EINTR)
continue;
if (r > 0)
on_stderr(ctx, buf, r);
if (r <= 0) {
close(p_stderr[0]);
p_stderr[0] = -1;
}
} }
if (fds[2].revents) { if (fds[2].revents) {
kill(pid, SIGKILL); kill(pid, SIGKILL);