On Thu, May 26, 2011 at 05:57:18PM +0200, Otto Moerbeek wrote:

> On Thu, May 26, 2011 at 07:02:55AM +0200, Otto Moerbeek wrote:
> 
> > Hi,
> > 
> > adding editline caused a regrssion in the handling of ^C.
> > 
> > Originally (and I mean the days of AT&T) bc used ^C as an abort line.
> > With editline, while appearing to work, the characters typed so far
> > remain in the input buffer. Try this: 1+^C2<enter>
> > 
> > Editline has no signal safe facility to accomodate that. So switch it
> > off (you can use ^U anyway). 
> > 
> > Also, honour the "edit off" command from .editrc or interactively. In
> > that case ^C works as before. 
> 
> Actually, after some more study I concluded that the non-wide chars
> code is safe. We don;t support wide chars editline now, and certainly
> will not in bc(1). So this should fare better, and have correct ^C
> handling both in editline mode and non-editline mode.

Nobody? I have another diff queued and I 'd like to make progress. So
if nobody objects, I'll commit tonight.

        -Otto

> 
> Index: bc.y
> ===================================================================
> RCS file: /cvs/src/usr.bin/bc/bc.y,v
> retrieving revision 1.34
> diff -u -p -r1.34 bc.y
> --- bc.y      7 Mar 2011 08:11:15 -0000       1.34
> +++ bc.y      26 May 2011 15:54:39 -0000
> @@ -1143,7 +1143,7 @@ main(int argc, char *argv[])
>                               history(hist, &he, H_SETSIZE, 100);
>                               el_set(el, EL_HIST, history, hist);
>                               el_set(el, EL_EDITOR, "emacs");
> -                             el_set(el, EL_SIGNAL, 1);
> +                             el_set(el, EL_SIGNAL, 0);
>                               el_set(el, EL_PROMPT, dummy_prompt);
>                               el_source(el, NULL);
>                       }
> Index: scan.l
> ===================================================================
> RCS file: /cvs/src/usr.bin/bc/scan.l,v
> retrieving revision 1.24
> diff -u -p -r1.24 scan.l
> --- scan.l    7 Mar 2011 08:11:15 -0000       1.24
> +++ scan.l    26 May 2011 15:54:39 -0000
> @@ -38,6 +38,8 @@ History             *hist;
>  static char  *strbuf = NULL;
>  static size_t        strbuf_sz = 1;
>  static bool  dot_seen;
> +static int   use_el;
> +static volatile sig_atomic_t skipchars;
>  
>  static void  init_strbuf(void);
>  static void  add_str(const char *);
> @@ -236,12 +238,18 @@ add_str(const char *str)
>  void
>  abort_line(int sig)
>  {
> -     static const char str[] = "[\n]P\n";
> +     static const char str1[] = "[\n]P\n";
> +     static const char str2[] = "[^C\n]P\n";
>       int save_errno;
> +     const LineInfo *info;
>  
>       save_errno = errno;
> -     YY_FLUSH_BUFFER;        /* XXX signal race? */
> -     write(STDOUT_FILENO, str, sizeof(str) - 1);
> +     if (use_el) {
> +             write(STDOUT_FILENO, str2, sizeof(str2) - 1);
> +             info = el_line(el);
> +             skipchars = info->lastchar - info->buffer;
> +     } else
> +             write(STDOUT_FILENO, str1, sizeof(str1) - 1);
>       errno = save_errno;
>  }
>  
> @@ -295,17 +303,32 @@ static int
>  bc_yyinput(char *buf, int maxlen)
>  {
>       int num;
> -     if (yyin == stdin && interactive) {
> +
> +     if (el != NULL)
> +             el_get(el, EL_EDITMODE, &use_el);
> +             
> +     if (yyin == stdin && interactive && use_el) {
>               const char *bp;
> +             sigset_t oset, nset;
>  
>               if ((bp = el_gets(el, &num)) == NULL || num == 0)
>                       return (0);
> +             sigemptyset(&nset);
> +             sigaddset(&nset, SIGINT);
> +             sigprocmask(SIG_BLOCK, &nset, &oset);
> +             if (skipchars < num) {
> +                     bp += skipchars;
> +                     num -= skipchars;
> +             }
> +             skipchars = 0;
> +             sigprocmask(SIG_SETMASK, &oset, NULL);
>               if (num > maxlen) {
>                       el_push(el, (char *)(void *)bp + maxlen);
>                       num = maxlen;
>               }
>               memcpy(buf, bp, num);
>               history(hist, &he, H_ENTER, bp);
> +             el_get(el, EL_EDITMODE, &use_el);
>       } else {
>               int c = '*';
>               for (num = 0; num < maxlen &&

Reply via email to