ido not keep getting a key if reading from stdin fail - iomenu - interactive terminal-based selection menu Err bitreich.org 70
hgit clone git://bitreich.org/iomenu git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/iomenu URL:git://bitreich.org/iomenu git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/iomenu bitreich.org 70
1Log /scm/iomenu/log.gph bitreich.org 70
1Files /scm/iomenu/files.gph bitreich.org 70
1Refs /scm/iomenu/refs.gph bitreich.org 70
1Tags /scm/iomenu/tag bitreich.org 70
1README /scm/iomenu/file/README.gph bitreich.org 70
1LICENSE /scm/iomenu/file/LICENSE.gph bitreich.org 70
i--- Err bitreich.org 70
1commit ab7bc829f2023b41b1edcf1926aa6a973169de41 /scm/iomenu/commit/ab7bc829f2023b41b1edcf1926aa6a973169de41.gph bitreich.org 70
1parent 3d11052f21bd037d4ba92b875e8315016976dfc9 /scm/iomenu/commit/3d11052f21bd037d4ba92b875e8315016976dfc9.gph bitreich.org 70
hAuthor: Josuah Demangeon <mail@josuah.net> URL:mailto:mail@josuah.net bitreich.org 70
iDate: Wed, 11 Apr 2018 22:03:43 +0200 Err bitreich.org 70
i Err bitreich.org 70
ido not keep getting a key if reading from stdin fail Err bitreich.org 70
i Err bitreich.org 70
iDiffstat: Err bitreich.org 70
i M iomenu.c | 60 +++++++++++++++++++------------- Err bitreich.org 70
i Err bitreich.org 70
i1 file changed, 36 insertions(+), 24 deletions(-) Err bitreich.org 70
i--- Err bitreich.org 70
1diff --git a/iomenu.c b/iomenu.c /scm/iomenu/file/iomenu.c.gph bitreich.org 70
i@@ -21,7 +21,6 @@ Err bitreich.org 70
i Err bitreich.org 70
i static struct termios termios; Err bitreich.org 70
i struct winsize ws; Err bitreich.org 70
i-static int ttyfd; Err bitreich.org 70
i static int linec = 0, matchc = 0, cur = 0; Err bitreich.org 70
i static char **linev = NULL, **matchv = NULL; Err bitreich.org 70
i static char input[LINE_MAX]; Err bitreich.org 70
i@@ -29,8 +28,8 @@ static int hsflag = 0; Err bitreich.org 70
i char *argv0; Err bitreich.org 70
i Err bitreich.org 70
i /* Err bitreich.org 70
i-** Keep the line if it match every token (in no particular order, and allowed to Err bitreich.org 70
i-** be overlapping). Err bitreich.org 70
i+** Keep the line if it match every token (in no particular order, Err bitreich.org 70
i+** and allowed to be overlapping). Err bitreich.org 70
i */ Err bitreich.org 70
i static int Err bitreich.org 70
i match_line(char *line, char **tokv) Err bitreich.org 70
i@@ -44,18 +43,35 @@ match_line(char *line, char **tokv) Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i /* Err bitreich.org 70
i-** Free the structures, reset the terminal state and exit with an error message. Err bitreich.org 70
i+** Free the structures, reset the terminal state and exit with an Err bitreich.org 70
i+** error message. Err bitreich.org 70
i */ Err bitreich.org 70
i static void Err bitreich.org 70
i die(const char *s) Err bitreich.org 70
i { Err bitreich.org 70
i- tcsetattr(ttyfd, TCSANOW, &termios); Err bitreich.org 70
i- close(ttyfd); Err bitreich.org 70
i+ if (tcsetattr(STDERR_FILENO, TCSANOW, &termios) == -1) Err bitreich.org 70
i+ perror("tcsetattr while dying"); Err bitreich.org 70
i+ close(STDERR_FILENO); Err bitreich.org 70
i perror(s); Err bitreich.org 70
i exit(EXIT_FAILURE); Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i /* Err bitreich.org 70
i+** Read one key from stdin and die if it failed to prevent to read Err bitreich.org 70
i+** in an endless loop. This caused the load average to go over 10 Err bitreich.org 70
i+** at work. :S Err bitreich.org 70
i+*/ Err bitreich.org 70
i+int Err bitreich.org 70
i+getkey(void) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ int c; Err bitreich.org 70
i+ Err bitreich.org 70
i+ if ((c = fgetc(stdin)) == EOF) Err bitreich.org 70
i+ die("getting a key"); Err bitreich.org 70
i+ return c; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+/* Err bitreich.org 70
i ** Split a buffer into an array of lines, without allocating memory for every Err bitreich.org 70
i ** line, but using the input buffer and replacing '\n' by '\0'. Err bitreich.org 70
i */ Err bitreich.org 70
i@@ -266,14 +282,14 @@ top: Err bitreich.org 70
i move(+1); Err bitreich.org 70
i break; Err bitreich.org 70
i case CSI('5'): /* page up */ Err bitreich.org 70
i- if (fgetc(stdin) != '~') Err bitreich.org 70
i+ if (getkey() != '~') Err bitreich.org 70
i break; Err bitreich.org 70
i /* FALLTHROUGH */ Err bitreich.org 70
i case ALT('v'): Err bitreich.org 70
i move_page(-1); Err bitreich.org 70
i break; Err bitreich.org 70
i case CSI('6'): /* page down */ Err bitreich.org 70
i- if (fgetc(stdin) != '~') Err bitreich.org 70
i+ if (getkey() != '~') Err bitreich.org 70
i break; Err bitreich.org 70
i /* FALLTHROUGH */ Err bitreich.org 70
i case CTL('V'): Err bitreich.org 70
i@@ -291,10 +307,10 @@ top: Err bitreich.org 70
i print_selection(); Err bitreich.org 70
i return 0; Err bitreich.org 70
i case ALT('['): Err bitreich.org 70
i- k = CSI(fgetc(stdin)); Err bitreich.org 70
i+ k = CSI(getkey()); Err bitreich.org 70
i goto top; Err bitreich.org 70
i case ESC: Err bitreich.org 70
i- k = ALT(fgetc(stdin)); Err bitreich.org 70
i+ k = ALT(getkey()); Err bitreich.org 70
i goto top; Err bitreich.org 70
i default: Err bitreich.org 70
i add_char((char) k); Err bitreich.org 70
i@@ -353,12 +369,12 @@ set_terminal(void) Err bitreich.org 70
i struct termios new; Err bitreich.org 70
i Err bitreich.org 70
i fputs("\x1b[s\x1b[?1049h\x1b[H", stderr); Err bitreich.org 70
i- if (tcgetattr(ttyfd, &termios) < 0 || tcgetattr(ttyfd, &new) < 0) { Err bitreich.org 70
i- perror("tcgetattr"); Err bitreich.org 70
i- exit(EXIT_FAILURE); Err bitreich.org 70
i- } Err bitreich.org 70
i+ if (tcgetattr(STDERR_FILENO, &termios) == -1 || Err bitreich.org 70
i+ tcgetattr(STDERR_FILENO, &new) == -1) Err bitreich.org 70
i+ die("setting terminal"); Err bitreich.org 70
i new.c_lflag &= ~(ICANON | ECHO | IEXTEN | IGNBRK | ISIG); Err bitreich.org 70
i- tcsetattr(ttyfd, TCSANOW, &new); Err bitreich.org 70
i+ if (tcsetattr(STDERR_FILENO, TCSANOW, &new) == -1) Err bitreich.org 70
i+ die("tcsetattr"); Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i /* Err bitreich.org 70
i@@ -368,7 +384,8 @@ static void Err bitreich.org 70
i reset_terminal(void) Err bitreich.org 70
i { Err bitreich.org 70
i fputs("\x1b[2J\x1b[u\033[?1049l", stderr); Err bitreich.org 70
i- tcsetattr(ttyfd, TCSANOW, &termios); Err bitreich.org 70
i+ if (tcsetattr(STDERR_FILENO, TCSANOW, &termios)) Err bitreich.org 70
i+ die("resetting terminal"); Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i static void Err bitreich.org 70
i@@ -378,7 +395,7 @@ sighandle(int sig) Err bitreich.org 70
i Err bitreich.org 70
i switch (sig) { Err bitreich.org 70
i case SIGWINCH: Err bitreich.org 70
i- if (ioctl(ttyfd, TIOCGWINSZ, &ws) < 0) Err bitreich.org 70
i+ if (ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1) Err bitreich.org 70
i die("ioctl"); Err bitreich.org 70
i print_screen(); Err bitreich.org 70
i break; Err bitreich.org 70
i@@ -403,11 +420,7 @@ init(void) Err bitreich.org 70
i filter(linec, linev); Err bitreich.org 70
i Err bitreich.org 70
i if (freopen("/dev/tty", "r", stdin) == NULL) Err bitreich.org 70
i- die("freopen /dev/tty"); Err bitreich.org 70
i- if (freopen("/dev/tty", "w", stderr) == NULL) Err bitreich.org 70
i- die("freopen /dev/tty"); Err bitreich.org 70
i- if ((ttyfd = open("/dev/tty", O_RDWR)) < 0) Err bitreich.org 70
i- die("open /dev/tty"); Err bitreich.org 70
i+ die("reopening /dev/tty as stdin"); Err bitreich.org 70
i Err bitreich.org 70
i set_terminal(); Err bitreich.org 70
i sighandle(SIGWINCH); Err bitreich.org 70
i@@ -436,12 +449,11 @@ main(int argc, char *argv[]) Err bitreich.org 70
i pledge("stdio tty", NULL); Err bitreich.org 70
i #endif Err bitreich.org 70
i Err bitreich.org 70
i- while ((exit_code = key(fgetc(stdin))) > 0) Err bitreich.org 70
i+ while ((exit_code = key(getkey())) > 0) Err bitreich.org 70
i print_screen(); Err bitreich.org 70
i Err bitreich.org 70
i print_screen(); Err bitreich.org 70
i reset_terminal(); Err bitreich.org 70
i- close(ttyfd); Err bitreich.org 70
i Err bitreich.org 70
i return exit_code; Err bitreich.org 70
i } Err bitreich.org 70
.
Response:
text/plain