From: Michael Tremer Date: Sun, 6 Oct 2024 12:39:09 +0000 (+0000) Subject: pty: Be less smart about the forwarding and make it work again X-Git-Tag: 0.9.30~1141 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83c0146a037c68b557e00a62eb120c0fff976477;p=pakfire.git pty: Be less smart about the forwarding and make it work again Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/pty.c b/src/libpakfire/pty.c index 098b45cd1..0d63d8bc3 100644 --- a/src/libpakfire/pty.c +++ b/src/libpakfire/pty.c @@ -79,70 +79,68 @@ struct pakfire_pty { /* Reads as much data as possible into the buffer */ -static int pakfire_pty_fill_buffer(struct pakfire_pty* pty, struct pakfire_pty_stdio* stdio) { +static int pakfire_pty_fill_buffer(struct pakfire_pty* pty, int fd, struct pakfire_pty_stdio* stdio) { int r; - for (;;) { - // Skip this if there is not space left in the buffer - if (stdio->buffered >= sizeof(stdio->buffer)) - return 0; - - // Fill the buffer - r = read(stdio->fd, stdio->buffer + stdio->buffered, sizeof(stdio->buffer) - stdio->buffered); - if (r < 0) { - switch (errno) { - case EAGAIN: - case EIO: - return 0; - - default: - return -errno; - } + // Skip this if there is not space left in the buffer + if (stdio->buffered >= sizeof(stdio->buffer)) + return 0; - // EOF - } else if (r == 0) { - return 0; + // Fill the buffer + r = read(fd, stdio->buffer + stdio->buffered, sizeof(stdio->buffer) - stdio->buffered); + if (r < 0) { + switch (errno) { + case EAGAIN: + case EIO: + break; - // Successful read - } else { - stdio->buffered += r; + default: + return -errno; } + + // EOF + } else if (r == 0) { + return 0; + + // Successful read + } else { + stdio->buffered += r; } + + return 0; } /* Writes as much data as possible from the buffer */ -static int pakfire_pty_drain_buffer(struct pakfire_pty* pty, struct pakfire_pty_stdio* stdio) { +static int pakfire_pty_drain_buffer(struct pakfire_pty* pty, int fd, struct pakfire_pty_stdio* stdio) { int r; // Do not try to write to an invalid file descriptor - if (stdio->fd < 0) + if (fd < 0) return 0; - for (;;) { - // Nothing to do if the buffer is empty - if (!stdio->buffered) - return 0; - - // Drain the buffer - r = write(stdio->fd, stdio->buffer, stdio->buffered); - if (r < 0) { - switch (errno) { - case EAGAIN: - case EIO: - return 0; - - default: - return -errno; - } + // Nothing to do if the buffer is empty + if (!stdio->buffered) + return 0; - // Successful write - } else { - memmove(stdio->buffer, stdio->buffer + r, stdio->buffered - r); + // Drain the buffer + r = write(fd, stdio->buffer, stdio->buffered); + if (r < 0) { + switch (errno) { + case EAGAIN: + case EIO: + break; - stdio->buffered -= r; + default: + return -errno; } + + // Successful write + } else { + memmove(stdio->buffer, stdio->buffer + r, stdio->buffered - r); + + stdio->buffered -= r; } return 0; @@ -157,7 +155,7 @@ static int pakfire_pty_forward(struct pakfire_pty* pty) { while (pty->master.io || pty->stdin.io || pty->stdout.io) { // Read from standard input if (pty->stdin.io & PAKFIRE_PTY_READY_TO_READ) { - r = pakfire_pty_fill_buffer(pty, &pty->stdin); + r = pakfire_pty_fill_buffer(pty, pty->stdin.fd, &pty->stdin); if (r < 0) { CTX_ERROR(pty->ctx, "Failed reading from standard input: %s\n", strerror(-r)); return r; @@ -173,20 +171,21 @@ static int pakfire_pty_forward(struct pakfire_pty* pty) { // Write to the master if (pty->master.io & PAKFIRE_PTY_READY_TO_WRITE) { - r = pakfire_pty_drain_buffer(pty, &pty->master); - if (r) { + r = pakfire_pty_drain_buffer(pty, pty->master.fd, &pty->stdin); + if (r < 0) { CTX_ERROR(pty->ctx, "Failed writing to the PTY: %s\n", strerror(-r)); return r; } // We are done writing for now - pty->master.io &= ~PAKFIRE_PTY_READY_TO_WRITE; + if (!pty->stdin.buffered) + pty->master.io &= ~PAKFIRE_PTY_READY_TO_WRITE; } // Read from the master if (pty->master.io & PAKFIRE_PTY_READY_TO_READ) { - r = pakfire_pty_fill_buffer(pty, &pty->master); - if (r) { + r = pakfire_pty_fill_buffer(pty, pty->master.fd, &pty->stdout); + if (r < 0) { CTX_ERROR(pty->ctx, "Failed reading from the PTY: %s\n", strerror(-r)); return r; } @@ -201,14 +200,15 @@ static int pakfire_pty_forward(struct pakfire_pty* pty) { // Write to standard output if (pty->stdout.io & PAKFIRE_PTY_READY_TO_WRITE) { - r = pakfire_pty_drain_buffer(pty, &pty->stdout); - if (r) { + r = pakfire_pty_drain_buffer(pty, pty->stdout.fd, &pty->stdout); + if (r < 0) { CTX_ERROR(pty->ctx, "Failed writing to standard output: %s\n", strerror(-r)); return r; } // We are done writing for now - pty->stdout.io &= ~PAKFIRE_PTY_READY_TO_WRITE; + if (!pty->stdout.buffered) + pty->stdout.io &= ~PAKFIRE_PTY_READY_TO_WRITE; } } @@ -288,6 +288,8 @@ static int pakfire_pty_enable_raw_mode(struct pakfire_pty* pty, struct pakfire_p if (!isatty(stdio->fd)) return 0; + CTX_DEBUG(pty->ctx, "Enabling raw mode on fd %d\n", stdio->fd); + // Store flags stdio->flags = fcntl(stdio->fd, F_GETFL); if (stdio->flags < 0) {