// Standard Input
struct pakfire_pty_stdio stdin;
struct pakfire_pty_stdio stdout;
+
+ // SIGWINCH Event
+ sd_event_source* sigwinch_event;
};
/*
return 0;
}
+/*
+ Forwards any window size changes.
+*/
+static int pakfire_pty_SIGWINCH(sd_event_source* source, const struct signalfd_siginfo* si, void* data) {
+ struct pakfire_pty* pty = data;
+ struct winsize size;
+ int r;
+
+ // Don't do anything if we have not been set up, yet
+ if (pty->stdout.fd < 0 || pty->master.fd < 0)
+ return 0;
+
+ // Fetch the new window size
+ r = ioctl(pty->stdout.fd, TIOCGWINSZ, &size);
+ if (r < 0)
+ return 0;
+
+ // Set the new window size
+ r = ioctl(pty->master.fd, TIOCSWINSZ, &size);
+ if (r < 0)
+ return 0;
+
+ return 0;
+}
+
static int pakfire_pty_activity(struct pakfire_pty* pty, struct pakfire_pty_stdio* stdio, uint32_t events) {
// Do we have data to read?
if (events & (EPOLLIN|EPOLLHUP))
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);
if (pty->socket[0] >= 0)
close(pty->socket[0]);
if (pty->socket[1] >= 0)
close(pty->master.fd);
pty->master.fd = -1;
+ // Listen to SIGWINCH
+ r = sd_event_add_signal(pty->loop, &pty->sigwinch_event,
+ SIGWINCH|SD_EVENT_SIGNAL_PROCMASK, pakfire_pty_SIGWINCH, pty);
+ if (r < 0) {
+ CTX_ERROR(pty->ctx, "Could not register SIGWINCH: %s\n", strerror(-r));
+ return r;
+ }
+
return 0;
}