diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2016-05-25 09:23:50 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2016-05-25 09:23:50 +0000 |
commit | 73c310e840366f437d3fcb845e4d79329dae8350 (patch) | |
tree | 0997bee709342b9c89fecdb16c55f1ecc5df2f4d | |
parent | 310140312968c930825729202f3e30ebd23a36e6 (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@
-rw-r--r-- | lib/libedit/el.h | 3 | ||||
-rw-r--r-- | lib/libedit/keymacro.c | 12 | ||||
-rw-r--r-- | lib/libedit/read.c | 46 |
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 |