From: Michael Tremer Date: Tue, 19 Dec 2023 16:33:00 +0000 (+0000) Subject: jail: Keep reading from/writing to PTY for as long as there is work to do X-Git-Tag: 0.9.30~1269 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6c7ddcdaf6ee56673b5d6a84781fa88c013f5a21;p=pakfire.git jail: Keep reading from/writing to PTY for as long as there is work to do Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/jail.c b/src/libpakfire/jail.c index 23a40d88e..a8c2bf48e 100644 --- a/src/libpakfire/jail.c +++ b/src/libpakfire/jail.c @@ -1066,74 +1066,81 @@ static int pakfire_jail_setup_pty_forwarding(struct pakfire_jail* jail, static int pakfire_jail_forward_pty(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx) { int r; - // Read from standard input - if (ctx->pty.stdin.flags & PAKFIRE_JAIL_PTY_READY_TO_READ) { - r = pakfire_jail_fill_buffer(jail, ctx->pty.stdin.fd, &ctx->pty.stdin.buffer); - if (r) { - CTX_ERROR(jail->ctx, "Failed reading from standard input: %s\n", strerror(-r)); - return r; - } + while (ctx->pty.master.flags || ctx->pty.stdin.flags || ctx->pty.stdout.flags) { + // Read from standard input + if (ctx->pty.stdin.flags & PAKFIRE_JAIL_PTY_READY_TO_READ) { + r = pakfire_jail_fill_buffer(jail, ctx->pty.stdin.fd, &ctx->pty.stdin.buffer); + if (r) { + CTX_ERROR(jail->ctx, "Failed reading from standard input: %s\n", strerror(-r)); + return r; + } - // We are done reading for now - ctx->pty.stdin.flags &= ~PAKFIRE_JAIL_PTY_READY_TO_READ; + printf("BUFFER %.*s\n", (int)ctx->pty.stdin.buffer.used, ctx->pty.stdin.buffer.data); - // But we may have data to write - if (ctx->pty.stdin.buffer.used) - ctx->pty.master.flags |= PAKFIRE_JAIL_PTY_READY_TO_WRITE; - } + // We are done reading for now + ctx->pty.stdin.flags &= ~PAKFIRE_JAIL_PTY_READY_TO_READ; - // Write to the master - if (ctx->pty.master.flags & PAKFIRE_JAIL_PTY_READY_TO_WRITE) { - r = pakfire_jail_drain_buffer(jail, ctx->pty.master.fd, &ctx->pty.stdin.buffer); - if (r) { - CTX_ERROR(jail->ctx, "Failed writing to the PTY: %s\n", strerror(-r)); - return r; + // But we may have data to write + if (ctx->pty.stdin.buffer.used) + ctx->pty.master.flags |= PAKFIRE_JAIL_PTY_READY_TO_WRITE; } - // We are done writing for now - ctx->pty.master.flags &= ~PAKFIRE_JAIL_PTY_READY_TO_WRITE; - } + // Write to the master + if (ctx->pty.master.flags & PAKFIRE_JAIL_PTY_READY_TO_WRITE) { + r = pakfire_jail_drain_buffer(jail, ctx->pty.master.fd, &ctx->pty.stdin.buffer); + if (r) { + CTX_ERROR(jail->ctx, "Failed writing to the PTY: %s\n", strerror(-r)); + return r; + } - // Read from the master - if (ctx->pty.master.flags & PAKFIRE_JAIL_PTY_READY_TO_READ) { - r = pakfire_jail_fill_buffer(jail, ctx->pty.master.fd, &ctx->pty.stdout.buffer); - if (r) { - CTX_ERROR(jail->ctx, "Failed reading from the PTY: %s\n", strerror(-r)); - return r; + // We are done writing for now + ctx->pty.master.flags &= ~PAKFIRE_JAIL_PTY_READY_TO_WRITE; } - // We are done reading for now - ctx->pty.master.flags &= ~PAKFIRE_JAIL_PTY_READY_TO_READ; - - // But we may have data to write - if (ctx->pty.stdout.buffer.used) - ctx->pty.stdout.flags |= PAKFIRE_JAIL_PTY_READY_TO_WRITE; - } - - // Write to standard output - if (ctx->pty.stdout.flags & PAKFIRE_JAIL_PTY_READY_TO_WRITE) { - // If we have a callback, we will send any output to the callback - if (ctx->communicate.out) { - r = pakfire_jail_drain_buffer_with_callback(jail, &ctx->pty.stdout.buffer, - LOG_INFO, ctx->communicate.out, ctx->communicate.data); - if (r) - return r; - - // If we have a file descriptor, we will forward any output - } else if (ctx->pty.stdout.fd >= 0) { - r = pakfire_jail_drain_buffer(jail, ctx->pty.stdout.fd, &ctx->pty.stdout.buffer); + // Read from the master + if (ctx->pty.master.flags & PAKFIRE_JAIL_PTY_READY_TO_READ) { + r = pakfire_jail_fill_buffer(jail, ctx->pty.master.fd, &ctx->pty.stdout.buffer); if (r) { - CTX_ERROR(jail->ctx, "Failed writing to standard output: %s\n", strerror(-r)); + CTX_ERROR(jail->ctx, "Failed reading from the PTY: %s\n", strerror(-r)); return r; } - // Otherwise we log a message - } else { - CTX_ERROR(jail->ctx, "No output configured for the PTY\n"); + // We are done reading for now + ctx->pty.master.flags &= ~PAKFIRE_JAIL_PTY_READY_TO_READ; + + // But we may have data to write + if (ctx->pty.stdout.buffer.used) + ctx->pty.stdout.flags |= PAKFIRE_JAIL_PTY_READY_TO_WRITE; } - // We are done writing for now - ctx->pty.stdout.flags &= ~PAKFIRE_JAIL_PTY_READY_TO_WRITE; + // Write to standard output + if (ctx->pty.stdout.flags & PAKFIRE_JAIL_PTY_READY_TO_WRITE) { + // If we have a callback, we will send any output to the callback + if (ctx->communicate.out) { + r = pakfire_jail_drain_buffer_with_callback(jail, &ctx->pty.stdout.buffer, + LOG_INFO, ctx->communicate.out, ctx->communicate.data); + if (r) + return r; + + // If we have a file descriptor, we will forward any output + } else if (ctx->pty.stdout.fd >= 0) { + r = pakfire_jail_drain_buffer(jail, ctx->pty.stdout.fd, &ctx->pty.stdout.buffer); + if (r) { + CTX_ERROR(jail->ctx, "Failed writing to standard output: %s\n", strerror(-r)); + return r; + } + + // Otherwise send the output to the default logger + } else { + r = pakfire_jail_drain_buffer_with_callback(jail, &ctx->pty.stdout.buffer, + LOG_INFO, pakfire_jail_default_log_callback, NULL); + if (r) + return r; + } + + // We are done writing for now + ctx->pty.stdout.flags &= ~PAKFIRE_JAIL_PTY_READY_TO_WRITE; + } } return 0;