From 3bcba8bb53d1c99cbe156facc3833771936d4f4f Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Tue, 18 Mar 2025 17:19:07 +0000 Subject: [PATCH] pty: Re-organise flags The CONNECT* flags have been used for two purposes which got mixed up on the way which is why the standard input was not connected for callbacks. Signed-off-by: Michael Tremer --- src/pakfire/pty.c | 57 ++++++++++++++++++++++++++--------------------- src/pakfire/pty.h | 11 +++------ 2 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/pakfire/pty.c b/src/pakfire/pty.c index 241071a3..ed5c5634 100644 --- a/src/pakfire/pty.c +++ b/src/pakfire/pty.c @@ -53,11 +53,12 @@ struct pakfire_pty_stdio { // IO Flags enum pakfire_pty_io { - PAKFIRE_PTY_READY_TO_READ = (1 << 0), - PAKFIRE_PTY_READY_TO_WRITE = (1 << 1), - PAKFIRE_PTY_HANGUP = (1 << 2), - PAKFIRE_PTY_EOF = (1 << 3), - PAKFIRE_PTY_MAP_CRNL = (1 << 4), + PAKFIRE_PTY_CONNECT = (1 << 0), + PAKFIRE_PTY_READY_TO_READ = (1 << 1), + PAKFIRE_PTY_READY_TO_WRITE = (1 << 2), + PAKFIRE_PTY_HANGUP = (1 << 3), + PAKFIRE_PTY_EOF = (1 << 4), + PAKFIRE_PTY_MAP_CRNL = (1 << 5), } io; // Event Source @@ -1073,7 +1074,7 @@ static int pakfire_pty_setup_forwarding(struct pakfire_pty* pty) { pty->state = PAKFIRE_PTY_STATE_FORWARDING; // Connect to standard input - if (pty->flags & PAKFIRE_PTY_CONNECT_STDIN) { + if (pakfire_pty_has_flag(pty, PAKFIRE_PTY_INTERACTIVE)) { pty->stdin.fd = pakfire_pty_reopen(pty, STDIN_FILENO, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NONBLOCK); if (pty->stdin.fd < 0) { DEBUG(pty->ctx, "Could not re-open standard input: %s. Ignoring.\n", strerror(-pty->stdin.fd)); @@ -1102,7 +1103,7 @@ static int pakfire_pty_setup_forwarding(struct pakfire_pty* pty) { pty->stdout.close_fd = 1; // Connect to standard output - } else if (pty->flags & PAKFIRE_PTY_CONNECT_STDOUT) { + } else if (pakfire_pty_has_flag(pty, PAKFIRE_PTY_INTERACTIVE)) { pty->stdout.fd = pakfire_pty_reopen(pty, STDOUT_FILENO, O_WRONLY|O_CLOEXEC|O_NOCTTY|O_NONBLOCK); if (pty->stdout.fd < 0) { DEBUG(pty->ctx, "Could not re-open standard output: %s. Ignoring.\n", strerror(-pty->stdout.fd)); @@ -1337,8 +1338,15 @@ int pakfire_pty_create(struct pakfire_pty** pty, struct pakfire_ctx* ctx, // Store the flags p->flags = flags; + // Connect stdout if we want to capture the output if (pakfire_pty_has_flag(p, PAKFIRE_PTY_CAPTURE_OUTPUT)) - p->flags |= PAKFIRE_PTY_CONNECT_STDOUT | PAKFIRE_PTY_CONNECT_STDERR; + p->stdout.io |= PAKFIRE_PTY_CONNECT; + + // Connect everything when we are in interactive mode + else if (pakfire_pty_has_flag(p, PAKFIRE_PTY_INTERACTIVE)) { + p->stdin.io |= PAKFIRE_PTY_CONNECT; + p->stdout.io |= PAKFIRE_PTY_CONNECT; + } // Initialize the master file descriptor p->master.fd = -EBADF; @@ -1451,7 +1459,7 @@ static int pakfire_pty_setup_terminal(struct pakfire_pty* pty) { DEBUG(pty->ctx, "Opened a new terminal %d\n", fd); // Connect the new terminal to standard input - if (pakfire_pty_has_flag(pty, PAKFIRE_PTY_CONNECT_STDIN)) { + if (pty->stdin.io & PAKFIRE_PTY_CONNECT) { r = dup2(fd, STDIN_FILENO); if (r < 0) { ERROR(pty->ctx, "Failed to open standard input: %s\n", strerror(errno)); @@ -1467,7 +1475,7 @@ static int pakfire_pty_setup_terminal(struct pakfire_pty* pty) { } // Connect the new terminal to standard output - if (pakfire_pty_has_flag(pty, PAKFIRE_PTY_CONNECT_STDOUT)) { + if (pty->stdout.io & PAKFIRE_PTY_CONNECT) { r = dup2(fd, STDOUT_FILENO); if (r < 0) { ERROR(pty->ctx, "Failed to open standard output: %s\n", strerror(errno)); @@ -1475,15 +1483,7 @@ static int pakfire_pty_setup_terminal(struct pakfire_pty* pty) { goto ERROR; } - // Otherwise we connect standard output to /dev/null - } else { - r = pakfire_pty_connect_null(pty, STDOUT_FILENO); - if (r < 0) - goto ERROR; - } - - // Connect the new terminal to standard error - if (pakfire_pty_has_flag(pty, PAKFIRE_PTY_CONNECT_STDERR)) { + // Connect stderr, too r = dup2(fd, STDERR_FILENO); if (r < 0) { ERROR(pty->ctx, "Failed to open standard error: %s\n", strerror(errno)); @@ -1491,8 +1491,13 @@ static int pakfire_pty_setup_terminal(struct pakfire_pty* pty) { goto ERROR; } - // Otherwise we connect standard error to /dev/null + // Otherwise we connect standard output to /dev/null } else { + r = pakfire_pty_connect_null(pty, STDOUT_FILENO); + if (r < 0) + goto ERROR; + + // Also redirect stderr r = pakfire_pty_connect_null(pty, STDERR_FILENO); if (r < 0) goto ERROR; @@ -1591,7 +1596,9 @@ void pakfire_pty_set_stdin_callback(struct pakfire_pty* pty, pty->stdin.callbacks.data = data; // We are now ready to read - pty->stdin.io |= PAKFIRE_PTY_READY_TO_READ; + pty->stdin.io |= + PAKFIRE_PTY_CONNECT | + PAKFIRE_PTY_READY_TO_READ; } void pakfire_pty_set_stdout_callback(struct pakfire_pty* pty, @@ -1600,10 +1607,10 @@ void pakfire_pty_set_stdout_callback(struct pakfire_pty* pty, pty->stdout.callbacks.data = data; // We are now ready to write - pty->stdout.io |= PAKFIRE_PTY_READY_TO_WRITE|PAKFIRE_PTY_MAP_CRNL; - - // Actually connect standard output and error - pty->flags |= PAKFIRE_PTY_CONNECT_STDOUT | PAKFIRE_PTY_CONNECT_STDERR; + pty->stdout.io |= + PAKFIRE_PTY_CONNECT | + PAKFIRE_PTY_READY_TO_WRITE | + PAKFIRE_PTY_MAP_CRNL; } ssize_t pakfire_pty_send_buffer(struct pakfire_ctx* ctx, diff --git a/src/pakfire/pty.h b/src/pakfire/pty.h index d6fc0d1c..3627e1f1 100644 --- a/src/pakfire/pty.h +++ b/src/pakfire/pty.h @@ -30,14 +30,9 @@ struct pakfire_pty; enum pakfire_pty_flags { - PAKFIRE_PTY_CONNECT_STDIN = (1 << 0), - PAKFIRE_PTY_CONNECT_STDOUT = (1 << 1), - PAKFIRE_PTY_CONNECT_STDERR = (1 << 2), - PAKFIRE_PTY_INTERACTIVE = \ - PAKFIRE_PTY_CONNECT_STDIN | \ - PAKFIRE_PTY_CONNECT_STDOUT| \ - PAKFIRE_PTY_CONNECT_STDERR, - PAKFIRE_PTY_CAPTURE_OUTPUT = (1 << 3), + PAKFIRE_PTY_NONE = 0, + PAKFIRE_PTY_INTERACTIVE = (1 << 0), + PAKFIRE_PTY_CAPTURE_OUTPUT = (1 << 1), }; int pakfire_pty_create(struct pakfire_pty** pty, -- 2.39.5