From: Michael Tremer Date: Sun, 6 Oct 2024 13:54:25 +0000 (+0000) Subject: pty: Disconnect as early as possible X-Git-Tag: 0.9.30~1137 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b3461de7bbf6f6224f49a409186cd669efffc085;p=pakfire.git pty: Disconnect as early as possible Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/pty.c b/src/libpakfire/pty.c index 047477a5f..4c09fc4d1 100644 --- a/src/libpakfire/pty.c +++ b/src/libpakfire/pty.c @@ -90,6 +90,62 @@ struct pakfire_pty { } state; }; +static int pakfire_pty_restore_attrs(struct pakfire_pty* pty, + struct pakfire_pty_stdio* stdio) { + int r; + + // Skip everything if fd is not a TTY + if (!isatty(stdio->fd)) + return 0; + + // Restore the flags + r = fcntl(stdio->fd, F_SETFL, stdio->flags); + if (r < 0) { + CTX_ERROR(pty->ctx, "Could not set flags for file descriptor %d: %s\n", + stdio->fd, strerror(errno)); + return -errno; + } + + // Restore the attributes + r = tcsetattr(stdio->fd, TCSANOW, &stdio->attrs); + if (r) { + CTX_ERROR(pty->ctx, "Could not restore terminal attributes for %d, ignoring: %s\n", + stdio->fd, strerror(errno)); + return -errno; + } + + // Close the file descriptor + close(stdio->fd); + stdio->fd = -1; + + return 0; +} + +static int pakfire_pty_disconnect(struct pakfire_pty* pty) { + if (pty->master.fd >= 0) { + close(pty->master.fd); + pty->master.fd = 1; + } + + // Restore any changed terminal attributes + if (pty->stdin.fd >= 0) + pakfire_pty_restore_attrs(pty, &pty->stdin); + if (pty->stdout.fd >= 0) + pakfire_pty_restore_attrs(pty, &pty->stdout); + + // Clear events + if (pty->master.event) + pty->master.event = sd_event_source_unref(pty->master.event); + if (pty->stdin.event) + pty->stdin.event = sd_event_source_unref(pty->stdin.event); + if (pty->stdout.event) + pty->stdout.event = sd_event_source_unref(pty->stdout.event); + if (pty->sigwinch_event) + pty->sigwinch_event = sd_event_source_unref(pty->sigwinch_event); + + return 0; +} + static int pakfire_pty_drained(struct pakfire_pty* pty) { int q; int r; @@ -133,6 +189,9 @@ static int pakfire_pty_done(struct pakfire_pty* pty, int code) { if (pty->state == PAKFIRE_PTY_STATE_DONE) return 0; + // Disconnect + pakfire_pty_disconnect(pty); + // Fetch a reference to the event loop loop = sd_event_ref(pty->loop); @@ -293,37 +352,6 @@ static int pakfire_pty_forward(struct pakfire_pty* pty) { return 0; } -static int pakfire_pty_restore_attrs(struct pakfire_pty* pty, - const struct pakfire_pty_stdio* stdio) { - int r; - - // Skip if we don't know the file descriptor - if (stdio->fd < 0) - return 0; - - // Skip everything if fd is not a TTY - if (!isatty(stdio->fd)) - return 0; - - // Restore the flags - r = fcntl(stdio->fd, F_SETFL, stdio->flags); - if (r < 0) { - CTX_ERROR(pty->ctx, "Could not set flags for file descriptor %d: %s\n", - stdio->fd, strerror(errno)); - return -errno; - } - - // Restore the attributes - r = tcsetattr(stdio->fd, TCSANOW, &stdio->attrs); - if (r) { - CTX_ERROR(pty->ctx, "Could not restore terminal attributes for %d, ignoring: %s\n", - stdio->fd, strerror(errno)); - return -errno; - } - - return 0; -} - /* Forwards any window size changes. */ @@ -611,25 +639,13 @@ static int pakfire_pty_setup(sd_event_source* source, int fd, uint32_t events, v } static void pakfire_pty_free(struct pakfire_pty* pty) { - // Restore any changed terminal attributes - if (pty->stdin.fd >= 0) - pakfire_pty_restore_attrs(pty, &pty->stdin); - if (pty->stdout.fd >= 0) - pakfire_pty_restore_attrs(pty, &pty->stdout); - if (pty->master.event) - sd_event_source_unref(pty->master.event); - if (pty->stdin.event) - sd_event_source_unref(pty->stdin.event); - if (pty->stdout.event) - sd_event_source_unref(pty->stdout.event); - if (pty->sigwinch_event) - sd_event_source_unref(pty->sigwinch_event); + pakfire_pty_disconnect(pty); + if (pty->socket[0] >= 0) close(pty->socket[0]); if (pty->socket[1] >= 0) close(pty->socket[1]); - if (pty->master.fd >= 0) - close(pty->master.fd); + if (pty->loop) sd_event_unref(pty->loop); if (pty->ctx)