summaryrefslogtreecommitdiff
path: root/lib/libedit
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2016-05-25 09:23:50 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2016-05-25 09:23:50 +0000
commit73c310e840366f437d3fcb845e4d79329dae8350 (patch)
tree0997bee709342b9c89fecdb16c55f1ecc5df2f4d /lib/libedit
parent310140312968c930825729202f3e30ebd23a36e6 (diff)
Saving errno in el_errno is only needed for one purpose:
Restoring the original errno found in el_wgetc() after el_wgets() did some cleanup that may have changed errno. Improve clarity and robustness of the code by not setting and inspecting el_errno where it isn't needed; in particular, let keymacro_get() properly report read failure to read_getcmd(). Move el_errno to el_read_t because it's only used in read.c. Never set errno back to zero. Checked with a test program installing a USR1 signal handler without SA_RESTART, for the cases read_getcmd(), ed_quoted_insert(), keymacro_get(), ed_command(), and EL_EDITMODE=0. OK czarkoff@
Diffstat (limited to 'lib/libedit')
-rw-r--r--lib/libedit/el.h3
-rw-r--r--lib/libedit/keymacro.c12
-rw-r--r--lib/libedit/read.c46
3 files changed, 26 insertions, 35 deletions
diff --git a/lib/libedit/el.h b/lib/libedit/el.h
index 0c9c88b6dbf..684dd681316 100644
--- a/lib/libedit/el.h
+++ b/lib/libedit/el.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: el.h,v 1.21 2016/05/20 15:30:17 schwarze Exp $ */
+/* $OpenBSD: el.h,v 1.22 2016/05/25 09:23:49 schwarze Exp $ */
/* $NetBSD: el.h,v 1.37 2016/04/18 17:01:19 christos Exp $ */
/*-
@@ -108,7 +108,6 @@ struct editline {
int el_outfd; /* Output file descriptor */
int el_errfd; /* Error file descriptor */
int el_flags; /* Various flags. */
- int el_errno; /* Local copy of errno */
coord_t el_cursor; /* Cursor location */
wchar_t **el_display; /* Real screen image = what is there */
wchar_t **el_vdisplay; /* Virtual screen image = what we see */
diff --git a/lib/libedit/keymacro.c b/lib/libedit/keymacro.c
index a7fa8ae34f3..21e7961a0a7 100644
--- a/lib/libedit/keymacro.c
+++ b/lib/libedit/keymacro.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: keymacro.c,v 1.15 2016/05/06 13:12:52 schwarze Exp $ */
-/* $NetBSD: keymacro.c,v 1.21 2016/04/18 17:01:19 christos Exp $ */
+/* $OpenBSD: keymacro.c,v 1.16 2016/05/25 09:23:49 schwarze Exp $ */
+/* $NetBSD: keymacro.c,v 1.23 2016/05/24 15:00:45 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -166,6 +166,7 @@ keymacro_reset(EditLine *el)
* complete match is found or a mismatch occurs. Returns the
* type of the match found (XK_STR or XK_CMD).
* Returns NULL in val.str and XK_STR for no match.
+ * Returns XK_NOD for end of file or read error.
* The last character read is returned in *ch.
*/
protected int
@@ -280,11 +281,8 @@ node_trav(EditLine *el, keymacro_node_t *ptr, wchar_t *ch,
/* match found */
if (ptr->next) {
/* key not complete so get next char */
- if (el_wgetc(el, ch) != 1) {/* if EOF or error */
- val->cmd = ED_END_OF_FILE;
- return XK_CMD;
- /* PWP: Pretend we just read an end-of-file */
- }
+ if (el_wgetc(el, ch) != 1)
+ return XK_NOD;
return node_trav(el, ptr->next, ch, val);
} else {
*val = ptr->val;
diff --git a/lib/libedit/read.c b/lib/libedit/read.c
index d26760010be..dc288825980 100644
--- a/lib/libedit/read.c
+++ b/lib/libedit/read.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: read.c,v 1.42 2016/05/24 18:06:30 schwarze Exp $ */
+/* $OpenBSD: read.c,v 1.43 2016/05/25 09:23:49 schwarze Exp $ */
/* $NetBSD: read.c,v 1.97 2016/05/22 19:44:26 christos Exp $ */
/*-
@@ -62,6 +62,7 @@ struct macros {
struct el_read_t {
struct macros macros;
el_rfunc_t read_char; /* Function to read a character. */
+ int read_errno;
};
static int read__fixio(int, int);
@@ -223,12 +224,9 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, wchar_t *ch)
el_action_t cmd;
int num;
- el->el_errno = 0;
do {
- if ((num = el_wgetc(el, ch)) != 1) {/* if EOF or error */
- el->el_errno = num == 0 ? 0 : errno;
+ if ((num = el_wgetc(el, ch)) != 1)
return -1;
- }
#ifdef KANJI
if ((*ch & meta)) {
@@ -255,6 +253,8 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, wchar_t *ch)
case XK_STR:
el_wpush(el, val.str);
break;
+ case XK_NOD:
+ return -1;
default:
EL_ABORT((el->el_errfile, "Bad XK_ type \n"));
break;
@@ -407,8 +407,15 @@ el_wgetc(EditLine *el, wchar_t *cp)
return 0;
num_read = (*el->el_read->read_char)(el, cp);
+
+ /*
+ * Remember the original reason of a read failure
+ * such that el_wgets() can restore it after doing
+ * various cleanup operation that might change errno.
+ */
if (num_read < 0)
- el->el_errno = errno;
+ el->el_read->read_errno = errno;
+
return num_read;
}
@@ -456,6 +463,7 @@ el_wgets(EditLine *el, int *nread)
if (nread == NULL)
nread = &nrb;
*nread = 0;
+ el->el_read->read_errno = 0;
if (el->el_flags & NO_TTY) {
size_t idx;
@@ -476,12 +484,8 @@ el_wgets(EditLine *el, int *nread)
if (cp[-1] == '\r' || cp[-1] == '\n')
break;
}
- if (num == -1) {
- if (errno == EINTR)
- cp = el->el_line.buffer;
- el->el_errno = errno;
- }
-
+ if (num == -1 && errno == EINTR)
+ cp = el->el_line.buffer;
goto noedit;
}
@@ -530,13 +534,8 @@ el_wgets(EditLine *el, int *nread)
if (crlf)
break;
}
-
- if (num == -1) {
- if (errno == EINTR)
- cp = el->el_line.buffer;
- el->el_errno = errno;
- }
-
+ if (num == -1 && errno == EINTR)
+ cp = el->el_line.buffer;
goto noedit;
}
@@ -544,12 +543,6 @@ el_wgets(EditLine *el, int *nread)
/* if EOF or error */
if (read_getcmd(el, &cmdnum, &ch) == -1)
break;
- if (el->el_errno == EINTR) {
- el->el_line.buffer[0] = '\0';
- el->el_line.lastchar =
- el->el_line.cursor = el->el_line.buffer;
- break;
- }
if ((int)cmdnum >= el->el_map.nfunc) /* BUG CHECK command */
continue; /* try again */
/* now do the real command */
@@ -650,7 +643,8 @@ done:
if (*nread == 0) {
if (num == -1) {
*nread = -1;
- errno = el->el_errno;
+ if (el->el_read->read_errno)
+ errno = el->el_read->read_errno;
}
return NULL;
} else