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);
 }