NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/48821: libedit EL_SETTY doesn't work



>Number:         48821
>Category:       lib
>Synopsis:       libedit EL_SETTY doesn't work
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon May 19 04:25:00 +0000 2014
>Originator:     yasuoka%iij.ad.jp@localhost
>Release:        NetBSD 5.1.2
>Organization:
Internet Initiative Japan
>Environment:
System: NetBSD yasuoka-nb.tokyo.iiji.jp 5.1.2 NetBSD 5.1.2 (GENERIC) #0: Thu 
Feb 2 12:12:28 UTC 2012 
builds%b7.netbsd.org@localhost:/home/builds/ab/netbsd-5-1-2-RELEASE/amd64/201202021012Z-obj/home/bui
lds/ab/netbsd-5-1-2-RELEASE/src/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:

As the man page of editline(3) and editrc(5), the parameter "EL_SETTY"
can configure the terminal setting.  By using this parameter, program
must be able to setup -ISIG not to receive SIGINT by Ctrl-C like
followings:

        el_set(el, EL_SETTY, "-d", "-isig", NULL);

but this doesn't work.

In tty_rawmode() of lib/libedit/tty.c, the library seems to skip
applying the clear/set flag bits from "EL_SETTY" if the current
termios flags is not changed from cached flags.

In lib/libedit/tty.c:
    991                 if ((el->el_tty.t_ts.c_lflag != 
el->el_tty.t_ex.c_lflag) &&
    992                     (el->el_tty.t_ts.c_lflag != 
el->el_tty.t_ed.c_lflag)) {

Only if flags are changed from the cached flags,

    993                         el->el_tty.t_ex.c_lflag =
    994                             el->el_tty.t_ts.c_lflag;
    995                         el->el_tty.t_ex.c_lflag &=
    996                             ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
    997                         el->el_tty.t_ex.c_lflag |=
    998                             el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;

the {set,clr}masks come from "EL_SETTY" are applied.  If any mask is
changed by "EL_SETTY", it must be applied.

>How-To-Repeat:

1. compile "libedittest.c" below
2. execute libedittest
3. enter Ctrl-C
-> the program will be interrupted

*** start libedittest.c ***
/* usage: cc -o libedittest libedittest.c -ledit -ltermcap */
#include <err.h>
#include <histedit.h>
#include <stdlib.h>
#include <termios.h>

static const char * prompt (EditLine *);

int
main(int argc, char *argv[])
{
        extern char     *__progname;
        int              num;
        EditLine        *el;
        const char      *line;

        el = el_init(__progname, stdin, stdout, stderr);
        el_set(el, EL_PROMPT, prompt);
        el_set(el, EL_EDITOR, "emacs");
        el_set(el, EL_SETTY, "-d", "-isig", NULL);
        for (;;) {
                line = el_gets(el, &num);
                if (line == NULL)
                        break;
        }
        el_end(el);

        exit(EXIT_SUCCESS);
}

static const char *
prompt(EditLine *el)
{
        return "> ";
}
*** end libedittest.c ***

>Fix:

Index: tty.c
===================================================================
RCS file: /var/cvs/netbsd/src/lib/libedit/tty.c,v
retrieving revision 1.27
diff -u -p -r1.27 tty.c
--- tty.c       10 Sep 2008 15:45:37 -0000      1.27
+++ tty.c       19 May 2014 03:41:49 -0000
@@ -456,6 +456,7 @@ private void        tty__getchar(struct termios
 private void   tty__setchar(struct termios *, unsigned char *);
 private speed_t        tty__getspeed(struct termios *);
 private int    tty_setup(EditLine *);
+private void   tty_setup_flags(EditLine *, struct termios *, int);
 
 #define        t_qu    t_ts
 
@@ -507,17 +508,7 @@ tty_setup(EditLine *el)
        el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
        el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
 
-       el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
-       el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
-
-       el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
-       el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
-
-       el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
-       el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
-
-       el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
-       el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
+       tty_setup_flags(el, &el->el_tty.t_ex, EX_IO);
 
        /*
          * Reset the tty chars to reasonable defaults
@@ -557,17 +548,7 @@ tty_setup(EditLine *el)
                tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
 #endif
 
-       el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
-       el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
-
-       el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
-       el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
-
-       el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
-       el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
-
-       el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
-       el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
+       tty_setup_flags(el, &el->el_tty.t_ed, ED_IO);
 
        tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
        tty_bind_char(el, 1);
@@ -964,69 +945,17 @@ tty_rawmode(EditLine *el)
                (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
        }
        if (tty__cooked_mode(&el->el_tty.t_ts)) {
-               if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
-                       el->el_tty.t_ex.c_cflag =
-                           el->el_tty.t_ts.c_cflag;
-                       el->el_tty.t_ex.c_cflag &=
-                           ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
-                       el->el_tty.t_ex.c_cflag |=
-                           el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
-
-                       el->el_tty.t_ed.c_cflag =
-                           el->el_tty.t_ts.c_cflag;
-                       el->el_tty.t_ed.c_cflag &=
-                           ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
-                       el->el_tty.t_ed.c_cflag |=
-                           el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
-               }
-               if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
-                   (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
-                       el->el_tty.t_ex.c_lflag =
-                           el->el_tty.t_ts.c_lflag;
-                       el->el_tty.t_ex.c_lflag &=
-                           ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
-                       el->el_tty.t_ex.c_lflag |=
-                           el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
-
-                       el->el_tty.t_ed.c_lflag =
-                           el->el_tty.t_ts.c_lflag;
-                       el->el_tty.t_ed.c_lflag &=
-                           ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
-                       el->el_tty.t_ed.c_lflag |=
-                           el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
-               }
-               if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
-                   (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
-                       el->el_tty.t_ex.c_iflag =
-                           el->el_tty.t_ts.c_iflag;
-                       el->el_tty.t_ex.c_iflag &=
-                           ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
-                       el->el_tty.t_ex.c_iflag |=
-                           el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
-
-                       el->el_tty.t_ed.c_iflag =
-                           el->el_tty.t_ts.c_iflag;
-                       el->el_tty.t_ed.c_iflag &=
-                           ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
-                       el->el_tty.t_ed.c_iflag |=
-                           el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
-               }
-               if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
-                   (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
-                       el->el_tty.t_ex.c_oflag =
-                           el->el_tty.t_ts.c_oflag;
-                       el->el_tty.t_ex.c_oflag &=
-                           ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
-                       el->el_tty.t_ex.c_oflag |=
-                           el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
-
-                       el->el_tty.t_ed.c_oflag =
-                           el->el_tty.t_ts.c_oflag;
-                       el->el_tty.t_ed.c_oflag &=
-                           ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
-                       el->el_tty.t_ed.c_oflag |=
-                           el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
-               }
+               el->el_tty.t_ed.c_iflag = el->el_tty.t_ex.c_iflag =
+                   el->el_tty.t_ts.c_iflag;
+               el->el_tty.t_ed.c_oflag = el->el_tty.t_ex.c_oflag =
+                   el->el_tty.t_ts.c_oflag;
+               el->el_tty.t_ed.c_cflag = el->el_tty.t_ex.c_cflag =
+                   el->el_tty.t_ts.c_cflag;
+               el->el_tty.t_ed.c_lflag = el->el_tty.t_ex.c_lflag =
+                   el->el_tty.t_ts.c_lflag;
+               tty_setup_flags(el, &el->el_tty.t_ex, EX_IO);
+               tty_setup_flags(el, &el->el_tty.t_ed, ED_IO);
+
                if (tty__gettabs(&el->el_tty.t_ex) == 0)
                        el->el_tty.t_tabs = 0;
                else
@@ -1120,18 +1049,7 @@ tty_quotemode(EditLine *el)
                return (0);
 
        el->el_tty.t_qu = el->el_tty.t_ed;
-
-       el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][MD_INP].t_clrmask;
-       el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][MD_INP].t_setmask;
-
-       el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][MD_OUT].t_clrmask;
-       el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][MD_OUT].t_setmask;
-
-       el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][MD_CTL].t_clrmask;
-       el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][MD_CTL].t_setmask;
-
-       el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask;
-       el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask;
+       tty_setup_flags(el, &el->el_tty.t_qu, QU_IO);
 
        if (tty_setty(el, TCSADRAIN, &el->el_tty.t_qu) == -1) {
 #ifdef DEBUG_TTY
@@ -1343,3 +1261,19 @@ tty_printchar(EditLine *el, unsigned cha
        (void) fprintf(el->el_errfile, "\n");
 }
 #endif /* notyet */
+
+private void
+tty_setup_flags(EditLine *el, struct termios *tios, int mode)
+{
+       tios->c_iflag &= ~el->el_tty.t_t[mode][MD_INP].t_clrmask;
+       tios->c_iflag |= el->el_tty.t_t[mode][MD_INP].t_setmask;
+
+       tios->c_oflag &= ~el->el_tty.t_t[mode][MD_OUT].t_clrmask;
+       tios->c_oflag |= el->el_tty.t_t[mode][MD_OUT].t_setmask;
+
+       tios->c_cflag &= ~el->el_tty.t_t[mode][MD_CTL].t_clrmask;
+       tios->c_cflag |= el->el_tty.t_t[mode][MD_CTL].t_setmask;
+
+       tios->c_lflag &= ~el->el_tty.t_t[mode][MD_LIN].t_clrmask;
+       tios->c_lflag |= el->el_tty.t_t[mode][MD_LIN].t_setmask;
+}



Home | Main Index | Thread Index | Old Index