summaryrefslogtreecommitdiffstats
path: root/input
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-02-19 22:18:15 +0100
committerwm4 <wm4@nowhere>2020-02-19 22:18:15 +0100
commite2ab6b7f3567542a2a1b5aab053d513737e72878 (patch)
tree36f3f24792e4974cf1e6c5601a61e799b098e69a /input
parentd06ebe2251b2ac75ebc6b63b1580ed15adecd3cc (diff)
downloadmpv-e2ab6b7f3567542a2a1b5aab053d513737e72878.tar.bz2
mpv-e2ab6b7f3567542a2a1b5aab053d513737e72878.tar.xz
scripting: add a way to run sub processes as "scripts"
This is just a more convenient way to start IPC client scripts per mpv instance. Does not work on Windows, although it could if the subprocess and IPC parts are implemented (and I guess .exe/.bat suffixes are required). Also untested whether it builds on Windows. A lot of other things are untested too, so don't complain.
Diffstat (limited to 'input')
-rw-r--r--input/input.h10
-rw-r--r--input/ipc-dummy.c6
-rw-r--r--input/ipc-unix.c51
-rw-r--r--input/ipc-win.c6
4 files changed, 63 insertions, 10 deletions
diff --git a/input/input.h b/input/input.h
index df51cb7ed4..1a90a47d42 100644
--- a/input/input.h
+++ b/input/input.h
@@ -213,10 +213,20 @@ void mp_input_sdl_gamepad_add(struct input_ctx *ictx);
struct mp_ipc_ctx;
struct mp_client_api;
+struct mpv_handle;
// Platform specific implementation, provided by ipc-*.c.
struct mp_ipc_ctx *mp_init_ipc(struct mp_client_api *client_api,
struct mpv_global *global);
+// Start a thread for the given handle and return a socket in out_fd[0] that
+// is served by this thread. If the FD is not full-duplex, then out_fd[0] is
+// the user's read-end, and out_fd[1] the write-end, otherwise out_fd[1] is set
+// to -1.
+// returns:
+// true: out_fd[0] and out_fd[1] are set, ownership of h is transferred
+// false: out_fd are not touched, caller retains ownership of h
+bool mp_ipc_start_anon_client(struct mp_ipc_ctx *ctx, struct mpv_handle *h,
+ int out_fd[2]);
void mp_uninit_ipc(struct mp_ipc_ctx *ctx);
// Serialize the given mpv_event structure to JSON. Returns an allocated string.
diff --git a/input/ipc-dummy.c b/input/ipc-dummy.c
index d9c31c046c..f0232b2f6e 100644
--- a/input/ipc-dummy.c
+++ b/input/ipc-dummy.c
@@ -8,6 +8,12 @@ struct mp_ipc_ctx *mp_init_ipc(struct mp_client_api *client_api,
return NULL;
}
+bool mp_ipc_start_anon_client(struct mp_ipc_ctx *ctx, struct mpv_handle *h,
+ int out_fd[2])
+{
+ return false;
+}
+
void mp_uninit_ipc(struct mp_ipc_ctx *ctx)
{
}
diff --git a/input/ipc-unix.c b/input/ipc-unix.c
index ef478ba35e..0a7f2a5838 100644
--- a/input/ipc-unix.c
+++ b/input/ipc-unix.c
@@ -58,7 +58,7 @@ struct client_arg {
struct mp_log *log;
struct mpv_handle *client;
- char *client_name;
+ const char *client_name;
int client_fd;
bool close_client_fd;
@@ -215,9 +215,11 @@ done:
return NULL;
}
-static void ipc_start_client(struct mp_ipc_ctx *ctx, struct client_arg *client)
+static bool ipc_start_client(struct mp_ipc_ctx *ctx, struct client_arg *client,
+ bool free_on_init_fail)
{
- client->client = mp_new_client(ctx->client_api, client->client_name);
+ if (!client->client)
+ client->client = mp_new_client(ctx->client_api, client->client_name);
if (!client->client)
goto err;
@@ -227,16 +229,19 @@ static void ipc_start_client(struct mp_ipc_ctx *ctx, struct client_arg *client)
if (pthread_create(&client_thr, NULL, client_thread, client))
goto err;
- return;
+ return true;
err:
- if (client->client)
- mpv_destroy(client->client);
+ if (free_on_init_fail) {
+ if (client->client)
+ mpv_destroy(client->client);
- if (client->close_client_fd)
- close(client->client_fd);
+ if (client->close_client_fd)
+ close(client->client_fd);
+ }
talloc_free(client);
+ return false;
}
static void ipc_start_client_json(struct mp_ipc_ctx *ctx, int id, int fd)
@@ -246,11 +251,37 @@ static void ipc_start_client_json(struct mp_ipc_ctx *ctx, int id, int fd)
.client_name = talloc_asprintf(client, "ipc-%d", id),
.client_fd = fd,
.close_client_fd = true,
+ .writable = true,
+ };
+ ipc_start_client(ctx, client, true);
+}
+
+bool mp_ipc_start_anon_client(struct mp_ipc_ctx *ctx, struct mpv_handle *h,
+ int out_fd[2])
+{
+ int pair[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair))
+ return false;
+
+ struct client_arg *client = talloc_ptrtype(NULL, client);
+ *client = (struct client_arg){
+ .client = h,
+ .client_name = mpv_client_name(h),
+ .client_fd = pair[1],
+ .close_client_fd = true,
.writable = true,
};
- ipc_start_client(ctx, client);
+ if (!ipc_start_client(ctx, client, false)) {
+ close(pair[0]);
+ close(pair[1]);
+ return false;
+ }
+
+ out_fd[0] = pair[0];
+ out_fd[1] = -1;
+ return true;
}
static void ipc_start_client_text(struct mp_ipc_ctx *ctx, const char *path)
@@ -292,7 +323,7 @@ static void ipc_start_client_text(struct mp_ipc_ctx *ctx, const char *path)
.writable = writable,
};
- ipc_start_client(ctx, client);
+ ipc_start_client(ctx, client, true);
}
static void *ipc_thread(void *p)
diff --git a/input/ipc-win.c b/input/ipc-win.c
index 727a8cca73..9672ec85fe 100644
--- a/input/ipc-win.c
+++ b/input/ipc-win.c
@@ -335,6 +335,12 @@ static void ipc_start_client_json(struct mp_ipc_ctx *ctx, int id, HANDLE h)
ipc_start_client(ctx, client);
}
+bool mp_ipc_start_anon_client(struct mp_ipc_ctx *ctx, struct mpv_handle *h,
+ int out_fd[2])
+{
+ return false;
+}
+
static void *ipc_thread(void *p)
{
// Use PIPE_TYPE_MESSAGE | PIPE_READMODE_BYTE so message framing is