Skip to content

Commit

Permalink
Use closefrom() to close open file descriptors
Browse files Browse the repository at this point in the history
Replace the naive close() loop in js_os_exec with closefrom().

On my system RLIMIT_NOFILE is set to 1 million and the delay from the
loop gets noticeable when I spawn many processes.

Use dlsym() to look up closefrom() because it's not available everywhere
(looking at you, musl.)

Fixes: #711
  • Loading branch information
bnoordhuis committed Nov 21, 2024
1 parent 769e78f commit c74923b
Showing 1 changed file with 21 additions and 4 deletions.
25 changes: 21 additions & 4 deletions quickjs-libc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2997,6 +2997,15 @@ static int my_execvpe(const char *filename, char **argv, char **envp)
return -1;
}

static js_once_t js_os_exec_once = JS_ONCE_INIT;

static void (*js_os_exec_closefrom)(int);

static void js_os_exec_once_init(void)
{
js_os_exec_closefrom = dlsym(RTLD_DEFAULT, "closefrom");
}

/* exec(args[, options]) -> exitcode */
static JSValue js_os_exec(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
Expand Down Expand Up @@ -3116,15 +3125,17 @@ static JSValue js_os_exec(JSContext *ctx, JSValue this_val,
}
}

// should happen pre-fork because it calls dlsym()
// and that's not an async-signal-safe function
js_once(&js_os_exec_once, js_os_exec_once_init);

pid = fork();
if (pid < 0) {
JS_ThrowTypeError(ctx, "fork error");
goto exception;
}
if (pid == 0) {
/* child */
int fd_max = sysconf(_SC_OPEN_MAX);

/* remap the stdin/stdout/stderr handles if necessary */
for(i = 0; i < 3; i++) {
if (std_fds[i] != i) {
Expand All @@ -3133,8 +3144,14 @@ static JSValue js_os_exec(JSContext *ctx, JSValue this_val,
}
}

for(i = 3; i < fd_max; i++)
close(i);
if (js_os_exec_closefrom) {
js_os_exec_closefrom(3);
} else {
int fd_max = sysconf(_SC_OPEN_MAX);
for(i = 3; i < fd_max; i++)
close(i);
}

if (cwd) {
if (chdir(cwd) < 0)
_exit(127);
Expand Down

0 comments on commit c74923b

Please sign in to comment.