commit 8582cb9cab300fe486cfeeb46142e3cfd9cfe962 Author: Steffen Daode Nurpmeso Date: 2012-09-10 15:50:58 +0200 Fix editline(3) char read and errno code flow The reading call chain failed to initialize local variables and also did not map return values that it got back from deeper in the call chain to its own meaning of those states, thus failing later due to misunderstanding. In addition the tracking of errno in EditLine::el_errno, and vice versa was also broken and is now fixed. diff --git a/lib/libedit/read.c b/lib/libedit/read.c index 7d7f54b..ecd1ee2 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); } @@ -426,7 +429,7 @@ el_gets(EditLine *el, int *nread) char *cp = el->el_line.buffer; size_t idx; - while ((*el->el_read.read_char)(el, cp) == 1) { + while ((num = (*el->el_read.read_char)(el, cp)) == 1) { /* make sure there is space for next character */ if (cp + 1 >= el->el_line.limit) { idx = (cp - el->el_line.buffer); @@ -479,7 +482,7 @@ el_gets(EditLine *el, int *nread) term__flush(el); - while ((*el->el_read.read_char)(el, cp) == 1) { + while ((num = (*el->el_read.read_char)(el, cp)) == 1) { /* make sure there is space next character */ if (cp + 1 >= el->el_line.limit) { idx = (cp - el->el_line.buffer); @@ -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);