Mercurial > projects > pwm
diff pager.c @ 19:5c6155c8e9b6
Handle signals
Handled signals are generally blocked and only unblocked when doing blocking
I/O, i.e. either when reading commands or printing results. A (possibly
queued) signal will then interrupt I/O and can be dealt with in the main loop.
author | Guido Berhoerster <guido+pwm@berhoerster.name> |
---|---|
date | Fri, 01 Sep 2017 22:33:41 +0200 |
parents | 1e39a251cbe9 |
children |
line wrap: on
line diff
--- a/pager.c Thu Aug 24 13:10:56 2017 +0200 +++ b/pager.c Fri Sep 01 22:33:41 2017 +0200 @@ -28,7 +28,6 @@ #endif /* HAVE_ERR_H */ #include <errno.h> #include <fcntl.h> -#include <libtecla.h> #include <limits.h> #include <signal.h> #include <stdio.h> @@ -49,7 +48,7 @@ struct pager { TAILQ_HEAD(lines_head, lines_entry) lines_head; - FILE *fp; + int fd; size_t buf_size; char *buf; }; @@ -59,32 +58,14 @@ char *line; }; -static int -getch_prompt(GetLine *gl, const char *prompt) -{ - int c; - int saved_echo_mode; - - /* 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), ""); - - return (c); -} - struct pager * -pager_create(FILE *fp) +pager_create(int fd) { struct pager *pager; pager = xmalloc(sizeof (struct pager)); TAILQ_INIT(&pager->lines_head); - pager->fp = fp; + pager->fd = fd; pager->buf_size = BUFSIZ; pager->buf = xmalloc(BUFSIZ); @@ -183,9 +164,10 @@ return (len); } -static unsigned int -mbsnprint(unsigned int cols, const char *s, FILE *fp) +static int +mbsnprint(unsigned int cols, const char *s, int fd) { + int retval; const char *p = s; unsigned int col = 0; int mb_len; @@ -232,21 +214,22 @@ p += mb_len; col += width; if (col <= cols) { - if (fputs(mb_buf, fp) == EOF) { - err(1, "fputs"); + retval = io_dputs(fd, mb_buf); + if (retval != IO_OK) { + return (retval); } } } - fputc('\n', fp); - fflush(fp); + retval = io_dputs(fd, "\n"); - return (col); + return (retval); } -void +enum io_status pager_show(struct pager *pager) { + int retval = IO_OK; int is_interactive; unsigned int rows = 24; unsigned int cols = 80; @@ -254,40 +237,45 @@ struct winsize ws; #endif /* TIOCGWINSZ */ unsigned int row = 0; - GetLine *gl; struct lines_entry *entry; + int c; - is_interactive = (isatty(STDIN_FILENO) && (pager->fp == stdout)); + is_interactive = (isatty(STDIN_FILENO) && (pager->fd == STDOUT_FILENO)); #ifdef TIOCGWINSZ if (is_interactive) { /* determine terminal size */ - if (ioctl(fileno(pager->fp), TIOCGWINSZ, &ws) == 0) { + if (ioctl(pager->fd, TIOCGWINSZ, &ws) == 0) { rows = (ws.ws_row > 0) ? ws.ws_row : rows; cols = (ws.ws_col > 0) ? ws.ws_col : cols; } } #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); + retval = mbsnprint(cols, entry->line, pager->fd); + if (retval != IO_OK) { + goto out; + } row++; if ((TAILQ_NEXT(entry, entry) != NULL) && (row == rows - 1)) { - getch_prompt(gl, "--More--"); + /* prompt for keypress */ + retval = io_get_char("--More--", &c); + if (retval != IO_OK) { + goto out; + } row = 0; } } else { - fprintf(pager->fp, "%s", entry->line); - fflush(pager->fp); + retval = io_dputs(pager->fd, entry->line); + if (retval != IO_OK) { + goto out; + } } } - del_GetLine(gl); +out: + return (retval); }