Semantics changes are the same as at 548ef078 . Also, the previous C implementation returnd a string for the `stdout` value, but stdout of the subprocess command is MPV_FORMAT_BYTE_ARRAY which js previously didn't support, so support it too (at pushnode) by returning it as a string - the same as the lua code does.
Showing the changes to player/javascript.c (1 of 2 files). Show all
Unified · Split
| @@ -920,31 +920,8 @@ static void script_get_user_path(js_State *J, void *af) · 919 unmodified lines | ||
| 920 | 920 | js_pushstring(J, mp_get_user_path(af, jctx(J)->mpctx->global, path)); |
| 921 | 921 | } |
| 922 | 922 | |
| 923 | −struct subprocess_cb_ctx { | |
| 924 | − struct mp_log *log; | |
| 925 | − void *talloc_ctx; | |
| 926 | − int64_t max_size; | |
| 927 | − bstr output; | |
| 928 | − bstr err; | |
| 929 | −}; | |
| 930 | − | |
| 931 | −static void subprocess_stdout(void *p, char *data, size_t size) | |
| 932 | −{ | |
| 933 | − struct subprocess_cb_ctx *ctx = p; | |
| 934 | − if (ctx->output.len < ctx->max_size) | |
| 935 | − bstr_xappend(ctx->talloc_ctx, &ctx->output, (bstr){data, size}); | |
| 936 | −} | |
| 937 | − | |
| 938 | −static void subprocess_stderr(void *p, char *data, size_t size) | |
| 939 | −{ | |
| 940 | − struct subprocess_cb_ctx *ctx = p; | |
| 941 | − if (ctx->err.len < ctx->max_size) | |
| 942 | − bstr_xappend(ctx->talloc_ctx, &ctx->err, (bstr){data, size}); | |
| 943 | − MP_INFO(ctx, "%.*s", (int)size, data); | |
| 944 | −} | |
| 945 | − | |
| 946 | −// args: client invocation args object. TODO: use common backend for js/lua | |
| 947 | −static void af_subprocess_common(js_State *J, int detach, void *af) | |
| 923 | +// args: client invocation args object | |
| 924 | +static void script_subprocess_detached(js_State *J, void *af) | |
| 948 | 925 | { |
| 949 | 926 | struct script_ctx *ctx = jctx(J); |
| 950 | 927 | if (!js_isobject(J, 1)) |
| @@ -969,52 +946,8 @@ static void af_subprocess_common(js_State *J, int detach, void *af) · 18 unmodified lines | ||
| 969 | 946 | } |
| 970 | 947 | args[num_args] = NULL; |
| 971 | 948 | |
| 972 | − if (detach) { | |
| 973 | − mp_subprocess_detached(ctx->log, args); | |
| 974 | − push_success(J); | |
| 975 | − return; | |
| 976 | − } | |
| 977 | − | |
| 978 | − struct mp_cancel *cancel = NULL; | |
| 979 | − if (js_hasproperty(J, 1, "cancellable") ? js_toboolean(J, -1) : true) | |
| 980 | − cancel = ctx->mpctx->playback_abort; | |
| 981 | − | |
| 982 | − int64_t max_size = js_hasproperty(J, 1, "max_size") ? js_tointeger(J, -1) | |
| 983 | − : 16 * 1024 * 1024; | |
| 984 | − struct subprocess_cb_ctx cb_ctx = { | |
| 985 | − .log = ctx->log, | |
| 986 | − .talloc_ctx = af, | |
| 987 | − .max_size = max_size, | |
| 988 | − }; | |
| 989 | − | |
| 990 | − char *error = NULL; | |
| 991 | − int status = mp_subprocess(args, cancel, &cb_ctx, subprocess_stdout, | |
| 992 | − subprocess_stderr, &error); | |
| 993 | − | |
| 994 | − js_newobject(J); // res | |
| 995 | − if (error) { | |
| 996 | − js_pushstring(J, error); // res e | |
| 997 | − js_setproperty(J, -2, "error"); // res | |
| 998 | − } | |
| 999 | − js_pushnumber(J, status); // res s | |
| 1000 | − js_setproperty(J, -2, "status"); // res | |
| 1001 | − js_pushlstring(J, cb_ctx.output.start, cb_ctx.output.len); // res d | |
| 1002 | − js_setproperty(J, -2, "stdout"); // res | |
| 1003 | − js_pushlstring(J, cb_ctx.err.start, cb_ctx.err.len); | |
| 1004 | − js_setproperty(J, -2, "stderr"); | |
| 1005 | − js_pushboolean(J, status == MP_SUBPROCESS_EKILLED_BY_US); // res b | |
| 1006 | − js_setproperty(J, -2, "killed_by_us"); // res | |
| 1007 | −} | |
| 1008 | − | |
| 1009 | −// args: client invocation args object (same also for _detached) | |
| 1010 | −static void script_subprocess(js_State *J, void *af) | |
| 1011 | −{ | |
| 1012 | − af_subprocess_common(J, 0, af); | |
| 1013 | −} | |
| 1014 | − | |
| 1015 | −static void script_subprocess_detached(js_State *J, void *af) | |
| 1016 | −{ | |
| 1017 | − af_subprocess_common(J, 1, af); | |
| 949 | + mp_subprocess_detached(ctx->log, args); | |
| 950 | + push_success(J); | |
| 1018 | 951 | } |
| 1019 | 952 | |
| 1020 | 953 | // args: none |
| @@ -1084,6 +1017,9 @@ static void pushnode(js_State *J, mpv_node *node) · 63 unmodified lines | ||
| 1084 | 1017 | case MPV_FORMAT_INT64: js_pushnumber(J, node->u.int64); break; |
| 1085 | 1018 | case MPV_FORMAT_DOUBLE: js_pushnumber(J, node->u.double_); break; |
| 1086 | 1019 | case MPV_FORMAT_FLAG: js_pushboolean(J, node->u.flag); break; |
| 1020 | + case MPV_FORMAT_BYTE_ARRAY: | |
| 1021 | + js_pushlstring(J, node->u.ba->data, node->u.ba->size); | |
| 1022 | + break; | |
| 1087 | 1023 | case MPV_FORMAT_NODE_ARRAY: |
| 1088 | 1024 | js_newarray(J); |
| 1089 | 1025 | len = node->u.list->num; |
| @@ -1360,7 +1296,6 @@ static const struct fn_entry utils_fns[] = { · 270 unmodified lines | ||
| 1360 | 1296 | FN_ENTRY(split_path, 1), |
| 1361 | 1297 | AF_ENTRY(join_path, 2), |
| 1362 | 1298 | AF_ENTRY(get_user_path, 1), |
| 1363 | − AF_ENTRY(subprocess, 1), | |
| 1364 | 1299 | AF_ENTRY(subprocess_detached, 1), |
| 1365 | 1300 | FN_ENTRY(getpid, 0), |
| 1366 | 1301 | |