summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2023-04-23 09:49:34 -0400
committerJakob Kaivo <jkk@ung.org>2023-04-23 09:49:34 -0400
commitad042959a56bba8478499f78dfce1ae876e092c4 (patch)
tree08c037a67914800a3763f50842a55be510c52dce
parente33af3b3e7ae0ecb806f94b2314106c24f048989 (diff)
properly set COLUMNS and LINESHEADmaster
-rw-r--r--interactive.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/interactive.c b/interactive.c
index 239c001..cad6867 100644
--- a/interactive.c
+++ b/interactive.c
@@ -19,13 +19,57 @@
#define _XOPEN_SOURCE 700
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+
+#ifdef SIGWINCH
+#include <sys/ioctl.h>
+#endif
#include "sh.h"
#include "shed.h"
+sig_atomic_t got_sigwinch = 0;
+static char sh_columns[8] = "80";
+static char sh_lines[8] = "25";
+
+#ifdef SIGWINCH
+static void sh_sigwinch(int sig)
+{
+ got_sigwinch = 1;
+ signal(sig, sh_sigwinch);
+}
+#endif
+
+void sh_getwinsize(void)
+{
+ #ifdef TIOCGWINSZ
+ struct winsize ws = { 0 };
+ ioctl(STDIN_FILENO, TIOCGWINSZ, &ws);
+ snprintf(sh_columns, sizeof(sh_columns), "%hhu", ws.ws_col);
+ snprintf(sh_lines, sizeof(sh_lines), "%hhu", ws.ws_row);
+ #else
+ FILE *cols = popen("tput cols", "r");
+ if (cols) {
+ fread(cols, 1, sizeof(sh_columns), sh_columns);
+ fclose(cols);
+ }
+
+ FILE *lines = popen("tput lines", "r");
+ if (lines) {
+ fread(lines, 1, sizeof(sh_lines), sh_lines);
+ fclose(lines);
+ }
+ #endif
+
+ setenv("COLUMNS", sh_columns, 1);
+ setenv("LINES", sh_lines, 1);
+}
+
int sh_interactive(void)
{
struct shed ed = {
@@ -33,6 +77,11 @@ int sh_interactive(void)
.handle = shed_handle_non_vi,
};
+ sh_getwinsize();
+ #ifdef SIGWINCH
+ signal(SIGWINCH, sh_sigwinch);
+ #endif
+
while (shed(&ed) != NULL) {
if (ed.cur->nread == 1 && ed.cur->buf[0] == CTRL_D) {
printf("\n");
@@ -44,6 +93,12 @@ int sh_interactive(void)
}
struct command *command = sh_parse(ed.cur->buf);
+ if (errno == SIGINT) {
+ if (got_sigwinch) {
+ sh_getwinsize();
+ }
+ }
+
if (command) {
sh_execute(command);
sh_freecmd(command);