Date: Sat, 08 Sep 2012 17:44:56 +0200 From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com> To: freebsd-bugs@FreeBSD.org Cc: jilles@FreeBSD.org, eadler@FreeBSD.org, markjdb@gmail.com Subject: Re: bin/169773: sh(1): Resizing causes /bin/sh to repeat edit operations Message-ID: <504b67f8.hU%2BoKTUxDdq8oHD59qxE1DdF@dietcurd.wild-life.local> In-Reply-To: <201209061926.q86JQwAC087821@freefall.freebsd.org> References: <201209061926.q86JQwAC087821@freefall.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
|Synopsis: sh(1): Resizing causes /bin/sh to repeat edit operations | |http://www.freebsd.org/cgi/query-pr.cgi?pr=169773 Oh, what a mess :) I agree with Mark that the handling of OKCMD is simply wrong, but it turned out to be wrong to simply use a different value for it. Also the passing through of errno is incomplete in there. (The documented interface doesn't state anything about errno or useful error handling at all, and however!) It's a rather quick first diff for editline(3), i have no more time but since it took almost three hours to come that far someone else may build on top of it (or simply try it or ... wait for a second). I *think* it effectively results in editline(3) behaving the way it is supposed to work (retrying once after a whatever signal, then failing for a second one). Since el_gets() now fails (as it is supposed to), sh(1) will behave wrong in that the current line gets "thrown away". (I guess the supposed way is to temporarily adjust PROMPT if one wants to continue what is on the line yet? But i still have no idea of editline(3) :->) It would be better if editline(3) could be configured to simply restart upon EINTR, or to fixate that behaviour (for FreeBSD)? I don't think it is acceptable to loose a line of user content due to a simple resize? So long and ciao, --steffen diff --git a/lib/libedit/read.c b/lib/libedit/read.c index 7d7f54b..5b51577 100644 --- a/lib/libedit/read.c +++ b/lib/libedit/read.c @@ -238,8 +238,7 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch) el->el_errno = 0; do { if ((num = el_getc(el, ch)) != 1) { /* if EOF or error */ - el->el_errno = num == 0 ? 0 : errno; - return (num); + return (num < 0 ? 1 : 0); } #ifdef KANJI @@ -294,16 +293,18 @@ read_char(EditLine *el, char *cp) again: el->el_signal->sig_no = 0; - while ((num_read = read(el->el_infd, cp, 1)) == -1) { + while ((num_read = read(el->el_infd, cp, 1)) < 0) { + int e = errno; if (el->el_signal->sig_no == SIGCONT) { sig_set(el); el_set(el, EL_REFRESH); goto again; } - if (!tried && read__fixio(el->el_infd, errno) == 0) + if (! tried && read__fixio(el->el_infd, e) == 0) tried = 1; else { *cp = '\0'; + errno = e; return (-1); } } @@ -369,8 +370,10 @@ el_getc(EditLine *el, char *cp) (void) fprintf(el->el_errfile, "Reading a character\n"); #endif /* DEBUG_READ */ num_read = (*el->el_read.read_char)(el, cp); + if (num_read < 0) + el->el_errno = errno; #ifdef DEBUG_READ - (void) fprintf(el->el_errfile, "Got it %c\n", *cp); + (void) fprintf(el->el_errfile, "Got <%c> (return %d)\n", *cp, num_read); #endif /* DEBUG_READ */ return (num_read); } @@ -511,6 +514,7 @@ el_gets(EditLine *el, int *nread) #endif /* DEBUG_EDIT */ /* if EOF or error */ if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) { + num = -1; #ifdef DEBUG_READ (void) fprintf(el->el_errfile, "Returning from el_gets %d\n", num);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?504b67f8.hU%2BoKTUxDdq8oHD59qxE1DdF>