Stop playing hopeless games with FIONBIO.
authorschwarze <schwarze@openbsd.org>
Thu, 12 Aug 2021 10:31:15 +0000 (10:31 +0000)
committerschwarze <schwarze@openbsd.org>
Thu, 12 Aug 2021 10:31:15 +0000 (10:31 +0000)
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
lib/libedit/read.c

index 0deef4a..c267bdf 100644 (file)
@@ -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
index 7900193..cd1b57f 100644 (file)
@@ -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 */