From 029afef8459eec855156b51de0a6b35a08280fb0 Mon Sep 17 00:00:00 2001 From: schwarze Date: Thu, 12 Aug 2021 10:31:15 +0000 Subject: [PATCH] Stop playing hopeless games with FIONBIO. If the calling program sets this flag, that is (1) either a bug (or at least needless) (2) or clearing it in el_wgets(3) will break other functionality of the calling program if it really requires it. In both cases, treating EAGAIN as a fatal error in el_wgets(3) is better than brushing the issue under the carpet: at least it tells the program author that something is amiss. Instead of attempting automatic repairs that will almost never do the right thing, clearly state in the manual page that the editline(3) library is not designed to work with non-blocking I/O. The problem was found while investigating a bug report from deraadt@ in sftp(1). OK millert@ and "mostly OK" martijn@ --- lib/libedit/editline.3 | 18 ++++++++++++++++-- lib/libedit/read.c | 36 +++--------------------------------- 2 files changed, 19 insertions(+), 35 deletions(-) diff --git a/lib/libedit/editline.3 b/lib/libedit/editline.3 index 0deef4aa88c..c267bdf8e81 100644 --- a/lib/libedit/editline.3 +++ b/lib/libedit/editline.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: editline.3,v 1.46 2016/05/22 22:08:42 schwarze Exp $ +.\" $OpenBSD: editline.3,v 1.47 2021/08/12 10:31:15 schwarze Exp $ .\" $NetBSD: editline.3,v 1.88 2016/02/25 14:59:22 wiz Exp $ .\" .\" Copyright (c) 1997-2003 The NetBSD Foundation, Inc. @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: May 22 2016 $ +.Dd $Mdocdate: August 12 2021 $ .Dt EDITLINE 3 .Os .Sh NAME @@ -169,6 +169,20 @@ Programs should be linked with .Pp The .Nm +library is designed to work with blocking I/O only. +If the +.Dv FIONBIO +.Xr ioctl 2 +is set on +.Ar fin , +.Fn el_gets +and +.Fn el_wgets +will almost certainly fail with +.Ar EAGAIN . +.Pp +The +.Nm library respects the .Ev LC_CTYPE locale set by the application program and never uses diff --git a/lib/libedit/read.c b/lib/libedit/read.c index 7900193aecc..cd1b57f2edd 100644 --- a/lib/libedit/read.c +++ b/lib/libedit/read.c @@ -1,4 +1,4 @@ -/* $OpenBSD: read.c,v 1.47 2021/08/11 15:13:46 martijn Exp $ */ +/* $OpenBSD: read.c,v 1.48 2021/08/12 10:31:15 schwarze Exp $ */ /* $NetBSD: read.c,v 1.100 2016/05/24 19:31:27 christos Exp $ */ /*- @@ -66,7 +66,6 @@ struct el_read_t { int read_errno; }; -static int read__fixio(int, int); static int read_char(EditLine *, wchar_t *); static int read_getcmd(EditLine *, el_action_t *, wchar_t *); static void read_clearmacros(struct macros *); @@ -132,26 +131,6 @@ el_read_getfn(struct el_read_t *el_read) } -/* read__fixio(): - * Try to recover from a read error - */ -static int -read__fixio(int fd, int e) -{ - int zero = 0; - - switch (e) { - case EAGAIN: - if (ioctl(fd, FIONBIO, &zero) == -1) - return -1; - return 0; - - default: - return -1; - } -} - - /* el_push(): * Push a macro */ @@ -231,15 +210,12 @@ static int read_char(EditLine *el, wchar_t *cp) { ssize_t num_read; - int tried = 0; char cbuf[MB_LEN_MAX]; int cbp = 0; - int save_errno = errno; again: el->el_signal->sig_no = 0; while ((num_read = read(el->el_infd, cbuf + cbp, 1)) == -1) { - int e = errno; if (errno == EINTR) { switch (el->el_signal->sig_no) { case SIGCONT: @@ -252,14 +228,8 @@ read_char(EditLine *el, wchar_t *cp) break; } } - if (!tried && read__fixio(el->el_infd, e) == 0) { - errno = save_errno; - tried = 1; - } else { - errno = e; - *cp = L'\0'; - return -1; - } + *cp = L'\0'; + return -1; } /* Test for EOF */ -- 2.20.1