aboutsummaryrefslogtreecommitdiffstats
path: root/pw.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-04-29 07:22:41 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-04-29 07:22:41 -0700
commit5d9e3f697908de66eb45a2af446de8365d2467df (patch)
tree462f7bada5acec9874a254df5fee731a30ade76d /pw.c
parent32d84fb2925e6f511fb8f8762ee02cb567095215 (diff)
downloadpw-5d9e3f697908de66eb45a2af446de8365d2467df.tar.gz
pw-5d9e3f697908de66eb45a2af446de8365d2467df.tar.bz2
pw-5d9e3f697908de66eb45a2af446de8365d2467df.zip
Handle terminal resizing.
Diffstat (limited to 'pw.c')
-rw-r--r--pw.c64
1 files changed, 57 insertions, 7 deletions
diff --git a/pw.c b/pw.c
index a7c62d4..8bb2184 100644
--- a/pw.c
+++ b/pw.c
@@ -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;