diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-04-29 07:22:41 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-04-29 07:22:41 -0700 |
commit | 5d9e3f697908de66eb45a2af446de8365d2467df (patch) | |
tree | 462f7bada5acec9874a254df5fee731a30ade76d /pw.c | |
parent | 32d84fb2925e6f511fb8f8762ee02cb567095215 (diff) | |
download | pw-5d9e3f697908de66eb45a2af446de8365d2467df.tar.gz pw-5d9e3f697908de66eb45a2af446de8365d2467df.tar.bz2 pw-5d9e3f697908de66eb45a2af446de8365d2467df.zip |
Handle terminal resizing.
Diffstat (limited to 'pw.c')
-rw-r--r-- | pw.c | 64 |
1 files changed, 57 insertions, 7 deletions
@@ -74,6 +74,8 @@ static unsigned ncmdhist; static char **pathist; static unsigned npathist; +volatile sig_atomic_t winch; + static void panic(const char *fmt, ...) { va_list vl; @@ -520,11 +522,26 @@ static void ttyget(int fd, struct termios *tty) panic("unable to get TTY parameters"); } +static void sigwinch(int sig) +{ + (void) sig; + winch = 1; +} + +static char **resizebuf(char **buf, size_t nlfrom, size_t nlto) +{ + if ((buf = realloc(buf, sizeof *buf * nlto)) == 0) + panic("out of memory"); + if (nlfrom < nlto) + memset(buf + nlfrom, 0, (nlto - nlfrom) * sizeof *buf); + return buf; +} + int main(int argc, char **argv) { char *line = 0; FILE *tty = fopen("/dev/tty", "r+"); - int maxlines = 15, nlines = 0; + int maxlines = 15, nlines = 0, maxed = 0; int opt; int fd = fileno(stdin); int ttyfd = tty ? fileno(tty) : -1; @@ -539,6 +556,9 @@ int main(int argc, char **argv) int auto_quit = 1; int exit_status = EXIT_FAILURE; char cmdbuf[cmdsize], *curcmd = 0, *savedcmd = 0; +#ifdef SIGWINCH + static struct sigaction sa; +#endif if (fd < 0) panic("unable to obtain input file descriptor"); @@ -599,8 +619,10 @@ int main(int argc, char **argv) } if (ioctl(ttyfd, TIOCGWINSZ, &ws) == 0 && ws.ws_row != 0) { - if (maxlines >= ws.ws_row) + if (maxlines >= ws.ws_row) { maxlines = ws.ws_row - 1; + maxed = 1; + } columns = ws.ws_col; } @@ -622,6 +644,11 @@ int main(int argc, char **argv) if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) panic("unable to set stdin nonblocking"); +#ifdef SIGWINCH + sa.sa_handler = sigwinch; + sigaction(SIGWINCH, &sa, NULL); +#endif + for (unsigned stat = stat_dirty, hpos = 0, kbd_state = kbd_cmd, kbd_prev = kbd_cmd, lasttime = ~0U, work = 1000, histpos = 0; @@ -695,6 +722,30 @@ int main(int argc, char **argv) nfds = 1; } + if (winch) { + winch = 0; + if (ioctl(ttyfd, TIOCGWINSZ, &ws) == 0) { + if (maxed) { + circbuf = resizebuf(circbuf, maxlines, ws.ws_row - 1); + snapshot = resizebuf(snapshot, maxlines, ws.ws_row - 1); + maxlines = ws.ws_row - 1; + } else { + if (maxlines >= ws.ws_row) { + maxlines = ws.ws_row - 1; + maxed = 1; + } + } + + if (nlines > maxlines) + nlines = maxlines; + if (snaplines > maxlines) + snaplines = maxlines; + + columns = ws.ws_col; + } + force = 1; + } + if ((stat & stat_eof)) pollms = -1; else if (nfds < 2) @@ -815,12 +866,11 @@ int main(int argc, char **argv) case '+': if (ws.ws_row && maxlines >= ws.ws_row - 1) break; + circbuf = resizebuf(circbuf, maxlines, maxlines + 1); + snapshot = resizebuf(snapshot, maxlines, maxlines + 1); maxlines++; - if ((circbuf = realloc(circbuf, sizeof *circbuf * maxlines)) == 0) - panic("out of memory"); - if ((snapshot = realloc(snapshot, sizeof *snapshot * maxlines)) == 0) - panic("out of memory"); - snapshot[maxlines-1] = circbuf[maxlines-1] = 0; + if (maxlines == ws.ws_row - 1) + maxed = 1; break; } break; |