diff options
author | Jakob Kaivo <jkk@ung.org> | 2020-07-14 16:36:13 -0400 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2020-07-14 16:36:13 -0400 |
commit | c494561b43b264223b7a8f800221b7e87dbb67eb (patch) | |
tree | e069e36a4b51c0065cfae489f722708ee1401081 /tty.c | |
parent | 527e45ab5cc919caea9bfee9af1cf3da83028420 (diff) |
split tty specific stuff out to tty.c
Diffstat (limited to 'tty.c')
-rw-r--r-- | tty.c | 78 |
1 files changed, 78 insertions, 0 deletions
@@ -0,0 +1,78 @@ +#define _XOPEN_SOURCE 700 +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <termios.h> +#include <unistd.h> + +#include "more.h" + +static FILE *resetty = NULL; +static struct termios resettings = { 0 }; + +static void resetterm(void) +{ + tcsetattr(fileno(resetty), TCSANOW, &resettings); +} + +static int query_term(const char *cap, const char *variable, int def) +{ + int n = 0; + char cmd[64]; + snprintf(cmd, sizeof(cmd), "tput %s", cap); + FILE *f = popen(cmd, "r"); + if (f) { + if (fscanf(f, "%d", &n) != 1) { + n = 0; + } + pclose(f); + if (n != 0) { + return n; + } + } + + char *value = getenv(variable); + if (value) { + n = atoi(value); + } + return n ? n : def; +} + +struct more_tty more_open_tty(int lines) +{ + struct more_tty mt = { + .tty = stderr, + .lines = query_term("lines", "LINES", 24), + .columns = query_term("cols", "COLUMNS", 80), + }; + + if (lines > 0) { + mt.lines = lines; + } + + /* leave room for prompts */ + lines--; + + /* FIXME: only open /dev/tty if stderr is not readable */ + // if (!(fcntl(fileno(mt.tty), F_GETFL) & (O_WRONLY | O_RDWR))) { + mt.tty = fopen("/dev/tty", "rb+"); + // } + if (mt.tty == NULL) { + perror("Couldn't open tty for reading"); + exit(1); + } + + setbuf(mt.tty, NULL); + + tcgetattr(fileno(mt.tty), &resettings); + struct termios term = resettings; + term.c_lflag &= ~(ECHO | ICANON); + term.c_cc[VMIN] = 1; + term.c_cc[VTIME] = 0; + tcsetattr(fileno(mt.tty), TCSANOW, &term); + + resetty = mt.tty; + atexit(resetterm); + + return mt; +} |