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 &&