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 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 .