Mercurial > projects > pwm
diff pager.c @ 18:1e39a251cbe9
Use libtecla for interactive input
author | Guido Berhoerster <guido+pwm@berhoerster.name> |
---|---|
date | Thu, 24 Aug 2017 13:10:56 +0200 |
parents | a08ef0674d8e |
children | 5c6155c8e9b6 |
line wrap: on
line diff
--- a/pager.c Sat Aug 12 10:41:52 2017 +0200 +++ b/pager.c Thu Aug 24 13:10:56 2017 +0200 @@ -28,6 +28,7 @@ #endif /* HAVE_ERR_H */ #include <errno.h> #include <fcntl.h> +#include <libtecla.h> #include <limits.h> #include <signal.h> #include <stdio.h> @@ -46,22 +47,6 @@ #include "pager.h" #include "util.h" -#ifndef TCSASOFT -#define TCSASOFT 0 -#endif /* !TCSASOFT */ - -#ifndef _NSIG -#ifdef NSIG -#define _NSIG NSIG -#else /* NSIG */ -#define _NSIG 128 -#endif /* NSIG */ -#endif /* !_NSIG */ - -#ifndef _PATH_TTY -#define _PATH_TTY "/dev/tty" -#endif - struct pager { TAILQ_HEAD(lines_head, lines_entry) lines_head; FILE *fp; @@ -74,123 +59,22 @@ char *line; }; -static volatile sig_atomic_t signals[_NSIG]; - -static void -sig_handler(int signo) -{ - signals[signo] = 1; -} - static int -getch_prompt(const char *prompt) +getch_prompt(GetLine *gl, const char *prompt) { - int retval = -1; - int signo; - int fd; - struct termios saved_term; - struct termios term; - struct sigaction sa; - struct sigaction saved_sa_hup; - struct sigaction saved_sa_int; - struct sigaction saved_sa_quit; - struct sigaction saved_sa_pipe; - struct sigaction saved_sa_alrm; - struct sigaction saved_sa_term; - struct sigaction saved_sa_tstp; - struct sigaction saved_sa_ttin; - struct sigaction saved_sa_ttou; - char c; - int need_restart = 0; - - printf("%s", prompt); - fflush(stdout); - -restart: - for (signo = 0; signo < _NSIG; signo++) { - signals[signo] = 0; - } - - fd = open(_PATH_TTY, O_RDONLY); - if (fd < 0) { - return (-1); - } + int c; + int saved_echo_mode; - if (tcgetattr(fd, &saved_term) != 0) { - close(fd); - return (-1); - } - memcpy(&term, &saved_term, sizeof (struct termios)); - - /* enter raw mode and turn echo off */ - term.c_lflag &= ~(ICANON | ECHO); - while ((tcsetattr(fd, TCSAFLUSH | TCSASOFT, &term) < 0) && - (errno != EINTR)) { - continue; - } - - /* install temporary signal handler */ - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = sig_handler; - sigaction(SIGHUP, &sa, &saved_sa_hup); - sigaction(SIGINT, &sa, &saved_sa_int); - sigaction(SIGQUIT, &sa, &saved_sa_quit); - sigaction(SIGPIPE, &sa, &saved_sa_pipe); - sigaction(SIGALRM, &sa, &saved_sa_alrm); - sigaction(SIGTERM, &sa, &saved_sa_term); - sigaction(SIGTSTP, &sa, &saved_sa_tstp); - sigaction(SIGTTIN, &sa, &saved_sa_ttin); - sigaction(SIGTTOU, &sa, &saved_sa_ttou); - - /* read key */ - if (read(fd, &c, 1) == sizeof (c)) { - retval = c; - } - - /* restore previous mode and echo setting */ - do { - while ((tcsetattr(fd, TCSAFLUSH | TCSASOFT, - &saved_term) < 0) && (errno != EINTR)) { - continue; - } - } while ((tcgetattr(fd, &term) == 0) && - (term.c_lflag != saved_term.c_lflag)); - - /* restore previous signal handlers */ - sigaction(SIGHUP, &saved_sa_hup, &sa); - sigaction(SIGINT, &saved_sa_int, &sa); - sigaction(SIGQUIT, &saved_sa_quit, &sa); - sigaction(SIGPIPE, &saved_sa_pipe, &sa); - sigaction(SIGALRM, &saved_sa_alrm, &sa); - sigaction(SIGTERM, &saved_sa_term, &sa); - sigaction(SIGTSTP, &saved_sa_tstp, &sa); - sigaction(SIGTTIN, &saved_sa_ttin, &sa); - sigaction(SIGTTOU, &saved_sa_ttou, &sa); + /* prompt with echo off */ + saved_echo_mode = gl_echo_mode(gl, -1); + gl_echo_mode(gl, 0); + c = gl_query_char(gl, prompt, '\0'); + gl_echo_mode(gl, saved_echo_mode); /* erase prompt */ printf("\r%*s\r", (int)strlen(prompt), ""); - fflush(stdout); - while ((close(fd) < 0) && (errno != EINTR)) { - continue; - } - - /* re-raise signals received */ - for (signo = 0; signo < _NSIG; signo++) { - if (signals[signo]) { - raise(signo); - if ((signo == SIGTSTP) || (signo == SIGTTIN) || - (signo == SIGTTOU)) { - need_restart = 1; - } - } - } - if (need_restart) { - goto restart; - } - - return (retval); + return (c); } struct pager * @@ -370,6 +254,7 @@ struct winsize ws; #endif /* TIOCGWINSZ */ unsigned int row = 0; + GetLine *gl; struct lines_entry *entry; is_interactive = (isatty(STDIN_FILENO) && (pager->fp == stdout)); @@ -384,12 +269,18 @@ } #endif /* TIOCGWINSZ */ + gl = new_GetLine(10, 0); + if (gl == NULL) { + err(1, "new_GetLine"); + } + TAILQ_FOREACH(entry, &pager->lines_head, entry) { if (is_interactive) { mbsnprint(cols, entry->line, pager->fp); row++; - if (row == rows - 1) { - getch_prompt("--More--"); + if ((TAILQ_NEXT(entry, entry) != NULL) && + (row == rows - 1)) { + getch_prompt(gl, "--More--"); row = 0; } } else { @@ -397,4 +288,6 @@ fflush(pager->fp); } } + + del_GetLine(gl); }