Files
eternalwrt-mt798x/package/utils/ucode/patches/111-uloop-add-optional-setup-callback-to-process.patch
T
Felix Fietkau 23ac692e6d ucode: update to Git HEAD (2026-07-09)
20a2ae469089 io: support older linux ioctls
16929698e2d3 fs: implement ioctl for macOS
395bb888bd69 io: implement ioctl for macOS
8d7d15ee1a08 compiler: add support for shorthand method declarations
7d9febd13305 nl80211: add mesh peer link enum macros to constants list
e851bb64df91 lib: avoid allocating print buffer before NULL check in uc_error_message_indent
5f3a7b87d962 compiler: prevent unbounded recompilation on failed module imports
e2493b577250 compiler: scope named function expression names to their own body
c3f0d27d812e tests: add regression test for named function expression scoping
738b55299966 vm: release owned value when property assignment fails
1ffd7c5a1011 vm: fix out-of-bounds read in single-name module import
a255256db106 vm: fix SIGFPE on INT64_MIN division and modulo by -1
3f4b313d7d78 vm: do not assign to undeclared variables in strict mode
e523682670a2 vm: release upvalue reference when resolving it on stack push
6a837090bea3 vm: release module scope reference in dynamic import
395a0a16b4f9 vm: guard error context capture against empty callframe stack
04f103bb2270 vm: respect exponent parity in integer exponentiation
bd814a4b2ae3 vm: use UC_ARRAY instead of json_type_array in object spread
5a79aa56c15e vm: release resource type prototypes after the final GC
9c5f16c8e33a lexer: do not treat /*/ as a complete block comment
a018067fd12e lexer: preserve NUL bytes in regular expression literals
65d41a1929de lexer: do not consume a sign into hexadecimal number literals
05f9bf9e5d53 lexer: fix source position of ternary question mark token
7bca646e5f88 lib: preserve embedded NUL bytes in reverse()
6fc93bf5bd95 lib: preserve embedded NUL bytes in lc() and uc()
a51f4843bce5 lib: avoid passing a signed char to isxdigit() in hex()
e8af70e4375c compiler: fix use-after-free of shorthand method name
467fb4406a47 compiler: declare leading variable in counting for loop initializer
d256e153799b rtnl: fix stack buffer overflow parsing IFLA_LINKINFO
f741ac0a144c rtnl: fix stack buffer overflow parsing RTA_MULTIPATH nexthops
c41310f7c2df rtnl: fix inverted address check in multipath nexthop parsing

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2026-07-16 11:50:22 +02:00

86 lines
3.1 KiB
Diff

From: Felix Fietkau <nbd@nbd.name>
Date: Wed, 8 Oct 2025 22:06:46 +0200
Subject: [PATCH] uloop: add optional setup callback to process()
Add optional setup callback as 5th argument to uloop.process() that is
invoked in the child process after fork() but before exec().
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/lib/uloop.c
+++ b/lib/uloop.c
@@ -973,8 +973,9 @@ uc_uloop_process_cb(struct uloop_process
*
* This function creates a process instance for executing external programs.
* It takes the executable path string, an optional string array as the argument
- * vector, an optional dictionary describing environment variables, and a
- * callback function to be invoked when the invoked process ends.
+ * vector, an optional dictionary describing environment variables, a
+ * callback function to be invoked when the invoked process ends, and an optional
+ * setup callback to be invoked in the child process after fork().
*
* @function module:uloop#process
*
@@ -991,6 +992,11 @@ uc_uloop_process_cb(struct uloop_process
* @param {Function} callback
* The callback function to be invoked when the invoked process ends.
*
+ * @param {Function} [setup]
+ * Optional. A callback function to be invoked in the child process after fork()
+ * but before exec(). This can be used to set up file descriptors, change working
+ * directory, or perform other initialization.
+ *
* @returns {?module:uloop.process}
* Returns a process instance for executing external programs.
* Returns `null` on error, e.g. due to `exec()` failure or invalid arguments.
@@ -1000,6 +1006,16 @@ uc_uloop_process_cb(struct uloop_process
* const myProcess = uloop.process("/bin/ls", ["-l", "/tmp"], null, (code) => {
* printf(`Process exited with code ${code}\n`);
* });
+ *
+ * // With setup callback to redirect stderr
+ * const myProcess = uloop.process("/bin/ls", ["-l", "/tmp"], null, (code) => {
+ * printf(`Process exited with code ${code}\n`);
+ * }, () => {
+ * const fs = require('fs');
+ * const errlog = fs.open('/tmp/error.log', 'w');
+ * fs.dup2(errlog.fileno(), 2);
+ * errlog.close();
+ * });
*/
static uc_value_t *
uc_uloop_process(uc_vm_t *vm, size_t nargs)
@@ -1008,6 +1024,7 @@ uc_uloop_process(uc_vm_t *vm, size_t nar
uc_value_t *arguments = uc_fn_arg(1);
uc_value_t *env_arg = uc_fn_arg(2);
uc_value_t *callback = uc_fn_arg(3);
+ uc_value_t *setup_cb = uc_fn_arg(4);
uc_uloop_process_t *process;
uc_stringbuf_t *buf;
char **argp, **envp;
@@ -1017,7 +1034,8 @@ uc_uloop_process(uc_vm_t *vm, size_t nar
if (ucv_type(executable) != UC_STRING ||
(arguments && ucv_type(arguments) != UC_ARRAY) ||
(env_arg && ucv_type(env_arg) != UC_OBJECT) ||
- !ucv_is_callable(callback)) {
+ !ucv_is_callable(callback) ||
+ (setup_cb && !ucv_is_callable(setup_cb))) {
err_return(EINVAL);
}
@@ -1027,6 +1045,13 @@ uc_uloop_process(uc_vm_t *vm, size_t nar
err_return(errno);
if (pid == 0) {
+ if (setup_cb) {
+ uc_vm_stack_push(vm, ucv_get(setup_cb));
+
+ if (uc_uloop_vm_call(vm, false, 0))
+ ucv_put(uc_vm_stack_pop(vm));
+ }
+
argp = calloc(ucv_array_length(arguments) + 2, sizeof(char *));
envp = environ;