diff options
author | wm4 <wm4@nowhere> | 2015-01-01 20:37:49 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-01-01 20:37:49 +0100 |
commit | 4c3f0427775273fe3925f631ea46891af56020aa (patch) | |
tree | 333c0c43c18efe64612618a7401fc4d788efe990 /player | |
parent | 44701238c73ba8f50fb16c675e2db3555902ac7a (diff) | |
download | mpv-4c3f0427775273fe3925f631ea46891af56020aa.tar.bz2 mpv-4c3f0427775273fe3925f631ea46891af56020aa.tar.xz |
command: make the "run" command work on Windows too
Do so by using mp_subprocess(). Although this uses completely different
code on Unix too, you shouldn't notice a difference. A less ncie thing
is that this reserves an entire thread while the command is running
(which wastes some memory for stack, at least). But this is probably
still the simplest way, and the fork() trick is apparently not
implementable with posix_subprocess().
Diffstat (limited to 'player')
-rw-r--r-- | player/command.c | 57 |
1 files changed, 35 insertions, 22 deletions
diff --git a/player/command.c b/player/command.c index 1739da76cb..9fb7c82c1c 100644 --- a/player/command.c +++ b/player/command.c @@ -60,11 +60,9 @@ #include "audio/decode/dec_audio.h" #include "options/path.h" #include "screenshot.h" -#ifndef __MINGW32__ -#include <sys/wait.h> -#endif #include "osdep/io.h" +#include "osdep/subprocess.h" #include "core.h" @@ -3920,6 +3918,39 @@ static void overlay_uninit(struct MPContext *mpctx) osd_set_external2(mpctx->osd, NULL); } +struct subprocess_args { + struct mp_log *log; + char **args; +}; + +static void *run_subprocess(void *ptr) +{ + struct subprocess_args *p = ptr; + pthread_detach(pthread_self()); + + mp_msg_flush_status_line(p->log); + + char *err = NULL; + if (mp_subprocess(p->args, NULL, NULL, NULL, NULL, &err) < 0) + mp_err(p->log, "Running subprocess failed: %s\n", err); + + talloc_free(p); + return NULL; +} + +static void subprocess_detached(struct mp_log *log, char **args) +{ + struct subprocess_args *p = talloc_zero(NULL, struct subprocess_args); + p->log = mp_log_new(p, log, NULL); + int num_args = 0; + for (int n = 0; args[n]; n++) + MP_TARRAY_APPEND(p, p->args, num_args, talloc_strdup(p, args[n])); + MP_TARRAY_APPEND(p, p->args, num_args, NULL); + pthread_t thread; + if (pthread_create(&thread, NULL, run_subprocess, p)) + talloc_free(p); +} + struct cycle_counter { char **args; int counter; @@ -4489,28 +4520,10 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd) break; case MP_CMD_RUN: { -#ifndef __MINGW32__ - mp_msg_flush_status_line(mpctx->global); char *args[MP_CMD_MAX_ARGS + 1] = {0}; for (int n = 0; n < cmd->nargs; n++) args[n] = cmd->args[n].v.s; - pid_t child = fork(); - if (child == 0) { - // Fork twice; the second process will be made child of pid 1 as - // soon as the first process exists, and we don't have to care - // about having to wait for the second process to terminate. - if (fork() == 0) { - execvp(args[0], args); - // mp_msg() is not safe to be called from a forked process. - char s[] = "Executing program failed.\n"; - write(2, s, sizeof(s) - 1); - _exit(1); - } - _exit(0); - } - int st; - while (child != -1 && waitpid(child, &st, 0) < 0 && errno == EINTR) {} -#endif + subprocess_detached(mpctx->log, args); break; } |