From: Michael Tremer Date: Mon, 24 Mar 2025 18:13:39 +0000 (+0000) Subject: jail: Only make the parent ends of the pipes non-blocking X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fb87a15ce1c4e9f9a9c8cfb424e19bfd530345d6;p=pakfire.git jail: Only make the parent ends of the pipes non-blocking Signed-off-by: Michael Tremer --- diff --git a/src/pakfire/jail.c b/src/pakfire/jail.c index 65ea4125..2e66363d 100644 --- a/src/pakfire/jail.c +++ b/src/pakfire/jail.c @@ -1239,6 +1239,11 @@ static int pakfire_jail_parent(struct pakfire_jail* jail, struct pakfire_jail_ex // Prepare standard input for writing fd = pakfire_jail_get_pipe_to_write(jail, &ctx->pipes.stdin); if (fd >= 0) { + r = pakfire_fd_set_non_blocking(jail->ctx, fd); + if (r < 0) + return r; + + // Add the file descriptor to the event loop r = sd_event_add_io(ctx->loop, NULL, fd, EPOLLOUT|EPOLLHUP|EPOLLET, pakfire_jail_stdin, ctx); if (r < 0) { ERROR(jail->ctx, "Failed to register standard input for writing: %s\n", strerror(-r)); @@ -1249,6 +1254,11 @@ static int pakfire_jail_parent(struct pakfire_jail* jail, struct pakfire_jail_ex // Prepare standard output for reading fd = pakfire_jail_get_pipe_to_read(jail, &ctx->pipes.stdout); if (fd >= 0) { + r = pakfire_fd_set_non_blocking(jail->ctx, fd); + if (r < 0) + return r; + + // Add the file descriptor to the event loop r = sd_event_add_io(ctx->loop, NULL, fd, EPOLLIN|EPOLLHUP|EPOLLET, pakfire_jail_stdout, ctx); if (r < 0) { ERROR(jail->ctx, "Failed to register standard output for reading: %s\n", strerror(-r)); @@ -1259,6 +1269,11 @@ static int pakfire_jail_parent(struct pakfire_jail* jail, struct pakfire_jail_ex // Prepare standard error for reading fd = pakfire_jail_get_pipe_to_read(jail, &ctx->pipes.stderr); if (fd >= 0) { + r = pakfire_fd_set_non_blocking(jail->ctx, fd); + if (r < 0) + return r; + + // Add the file descriptor to the event loop r = sd_event_add_io(ctx->loop, NULL, fd, EPOLLIN|EPOLLHUP|EPOLLET, pakfire_jail_stderr, ctx); if (r < 0) { ERROR(jail->ctx, "Failed to register standard error for reading: %s\n", strerror(-r)); @@ -1701,19 +1716,19 @@ static int __pakfire_jail_exec(struct pakfire_jail* jail, // Otherwise we are running a non-interactive session } else { // Create a pipe for the standard input only when a callback is set - if (stdin_callback) { - r = pakfire_jail_setup_pipe(jail, &ctx.pipes.stdin, O_NONBLOCK); + if (input_callback) { + r = pakfire_jail_setup_pipe(jail, &ctx.pipes.stdin, 0); if (r < 0) goto ERROR; } // Create a pipe for standard output - r = pakfire_jail_setup_pipe(jail, &ctx.pipes.stdout, O_NONBLOCK); + r = pakfire_jail_setup_pipe(jail, &ctx.pipes.stdout, 0); if (r < 0) goto ERROR; // Create a pipe for standard error - r = pakfire_jail_setup_pipe(jail, &ctx.pipes.stderr, O_NONBLOCK); + r = pakfire_jail_setup_pipe(jail, &ctx.pipes.stderr, 0); if (r < 0) goto ERROR; diff --git a/src/pakfire/util.c b/src/pakfire/util.c index 3debaf2c..bf2e856b 100644 --- a/src/pakfire/util.c +++ b/src/pakfire/util.c @@ -477,3 +477,24 @@ int pakfire_copy(struct pakfire_ctx* ctx, FILE* src, FILE* dst) { return 0; } + +int pakfire_fd_set_non_blocking(struct pakfire_ctx* ctx, int fd) { + int flags; + int r; + + // Fetch the flags + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) { + ERROR(ctx, "Could not set flags for file descriptor %d: %m\n", fd); + return -errno; + } + + // Turn on non-blocking mode + r = fcntl(fd, F_SETFL, flags | O_NONBLOCK); + if (r < 0) { + ERROR(ctx, "Could not set flags for file descriptor %d: %m\n", fd); + return -errno; + } + + return 0; +} diff --git a/src/pakfire/util.h b/src/pakfire/util.h index 5adb68ca..e72ffea7 100644 --- a/src/pakfire/util.h +++ b/src/pakfire/util.h @@ -91,6 +91,9 @@ int pakfire_compile_regex(struct pakfire_ctx* ctx, pcre2_code** regex, const cha // Copy int pakfire_copy(struct pakfire_ctx* ctx, FILE* src, FILE* dst); +// File Descriptors +int pakfire_fd_set_non_blocking(struct pakfire_ctx* ctx, int fd); + // Time // seconds to microseconds