| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- From: Felix Fietkau <[email protected]>
- 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 <[email protected]>
- ---
- --- a/lib/uloop.c
- +++ b/lib/uloop.c
- @@ -961,8 +961,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
- *
- @@ -979,6 +980,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.
- @@ -988,6 +994,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)
- @@ -996,6 +1012,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;
- @@ -1005,7 +1022,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);
- }
-
- @@ -1015,6 +1033,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;
-
|