summaryrefslogtreecommitdiffstats
path: root/osdep/subprocess.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-02-16 21:27:34 +0100
committerwm4 <wm4@nowhere>2020-02-16 21:27:34 +0100
commit92fee4ebc4852f023527dc64b28e5b10e4507053 (patch)
tree4d4e8c72a52384689cd7531132dbc3d861571661 /osdep/subprocess.c
parenta4b12c54b64f31e005adb8b07d7c45876e91f0f5 (diff)
downloadmpv-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.c59
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";
+ }
+}