diff options
author | wm4 <wm4@nowhere> | 2020-02-16 21:27:34 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2020-02-16 21:27:34 +0100 |
commit | 92fee4ebc4852f023527dc64b28e5b10e4507053 (patch) | |
tree | 4d4e8c72a52384689cd7531132dbc3d861571661 /osdep/subprocess.c | |
parent | a4b12c54b64f31e005adb8b07d7c45876e91f0f5 (diff) | |
download | mpv-92fee4ebc4852f023527dc64b28e5b10e4507053.tar.bz2 mpv-92fee4ebc4852f023527dc64b28e5b10e4507053.tar.xz |
subprocess: change to a fancier API
Introduce mp_subprocess() and related definitions. This is a bit more
flexible than the old stuff. This may or may not be used for a more
complicated feature that involves starting processes, and which would
require more control.
Only port subprocess-posix.c to this API. The player still uses the
"old" API, so for win32 and dummy implementations, the new API is simply
not available, while for POSIX, the old APIs are emulated on top of the
new one. I'm hoping the win32 code can be ported as well, so the ifdefs
in subprocess.c can be dropped, and the player can (if convenient or
needed) use the new API.
Diffstat (limited to 'osdep/subprocess.c')
-rw-r--r-- | osdep/subprocess.c | 59 |
1 files changed, 55 insertions, 4 deletions
diff --git a/osdep/subprocess.c b/osdep/subprocess.c index 1e94d23b67..9da5c10c1c 100644 --- a/osdep/subprocess.c +++ b/osdep/subprocess.c @@ -25,6 +25,48 @@ #include "subprocess.h" +void mp_devnull(void *ctx, char *data, size_t size) +{ +} + +#if HAVE_POSIX_SPAWN + +int mp_subprocess(char **args, struct mp_cancel *cancel, void *ctx, + subprocess_read_cb on_stdout, subprocess_read_cb on_stderr, + char **error) +{ + struct mp_subprocess_opts opts = { + .exe = args[0], + .args = args, + .cancel = cancel, + }; + opts.fds[opts.num_fds++] = (struct mp_subprocess_fd){ + .fd = 0, // stdin + .src_fd = 0, + }; + opts.fds[opts.num_fds++] = (struct mp_subprocess_fd){ + .fd = 1, // stdout + .on_read = on_stdout, + .on_read_ctx = ctx, + .src_fd = on_stdout ? -1 : 1, + }; + opts.fds[opts.num_fds++] = (struct mp_subprocess_fd){ + .fd = 2, // stderr + .on_read = on_stderr, + .on_read_ctx = ctx, + .src_fd = on_stderr ? -1 : 2, + }; + struct mp_subprocess_result res; + mp_subprocess2(&opts, &res); + if (res.error < 0) { + *error = (char *)mp_subprocess_err_str(res.error); + return res.error; + } + return res.exit_status; +} + +#endif + struct subprocess_args { struct mp_log *log; char **args; @@ -45,10 +87,6 @@ static void *run_subprocess(void *ptr) return NULL; } -void mp_devnull(void *ctx, char *data, size_t size) -{ -} - void mp_subprocess_detached(struct mp_log *log, char **args) { struct subprocess_args *p = talloc_zero(NULL, struct subprocess_args); @@ -61,3 +99,16 @@ void mp_subprocess_detached(struct mp_log *log, char **args) if (pthread_create(&thread, NULL, run_subprocess, p)) talloc_free(p); } + +const char *mp_subprocess_err_str(int num) +{ + // Note: these are visible to the public client API + switch (num) { + case MP_SUBPROCESS_OK: return "success"; + case MP_SUBPROCESS_EKILLED_BY_US: return "killed"; + case MP_SUBPROCESS_EINIT: return "init"; + case MP_SUBPROCESS_EUNSUPPORTED: return "unsupported"; + case MP_SUBPROCESS_EGENERIC: // fall through + default: return "unknown"; + } +} |