} 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;
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);
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.
*/
}
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)