Re-merge a couple of changes from NetBSD's libedit.

bin/sh has been taught about el_gets setting the count to -1
on error, so now we can partially revert r238173 to reduce
differences with NetBSD's implementation.

Unfortunately NetBSD's libedit handling of EINTR (Revision
1.44 in read.c + SIGWINCH fixes) still causes trouble in
bin/sh and other utilities and has to be avoided.

MFC after:	1 month
This commit is contained in:
Pedro F. Giffuni 2012-07-11 22:20:19 +00:00
parent 00c43e0ca4
commit c4fff9dd3a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=238378
5 changed files with 51 additions and 20 deletions

View File

@ -162,6 +162,11 @@ is modified to contain the number of characters read.
Returns the line read if successful, or Returns the line read if successful, or
.Dv NULL .Dv NULL
if no characters were read or if an error occurred. if no characters were read or if an error occurred.
If an error occurred,
.Fa count
is set to \-1 and
.Dv errno
contains the error code that caused it.
The return value may not remain valid across calls to The return value may not remain valid across calls to
.Fn el_gets .Fn el_gets
and must be copied if the data is to be retained. and must be copied if the data is to be retained.

View File

@ -115,6 +115,7 @@ struct editline {
FILE *el_errfile; /* Stdio stuff */ FILE *el_errfile; /* Stdio stuff */
int el_infd; /* Input file descriptor */ int el_infd; /* Input file descriptor */
int el_flags; /* Various flags. */ int el_flags; /* Various flags. */
int el_errno; /* Local copy of errno */
coord_t el_cursor; /* Cursor location */ coord_t el_cursor; /* Cursor location */
char **el_display; /* Real screen image = what is there */ char **el_display; /* Real screen image = what is there */
char **el_vdisplay; /* Virtual screen image = what we see */ char **el_vdisplay; /* Virtual screen image = what we see */

View File

@ -235,9 +235,12 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
el_action_t cmd; el_action_t cmd;
int num; int num;
el->el_errno = 0;
do { do {
if ((num = el_getc(el, ch)) != 1) /* if EOF or error */ if ((num = el_getc(el, ch)) != 1) { /* if EOF or error */
el->el_errno = num == 0 ? 0 : errno;
return (num); return (num);
}
#ifdef KANJI #ifdef KANJI
if ((*ch & 0200)) { if ((*ch & 0200)) {
@ -289,14 +292,21 @@ read_char(EditLine *el, char *cp)
ssize_t num_read; ssize_t num_read;
int tried = 0; int tried = 0;
while ((num_read = read(el->el_infd, cp, 1)) == -1) again:
el->el_signal->sig_no = 0;
while ((num_read = read(el->el_infd, cp, 1)) == -1) {
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, errno) == 0)
tried = 1; tried = 1;
else { else {
*cp = '\0'; *cp = '\0';
return (-1); return (-1);
} }
}
return (int)num_read; return (int)num_read;
} }
@ -403,10 +413,13 @@ el_gets(EditLine *el, int *nread)
int num; /* how many chars we have read at NL */ int num; /* how many chars we have read at NL */
char ch; char ch;
int crlf = 0; int crlf = 0;
int nrb;
#ifdef FIONREAD #ifdef FIONREAD
c_macro_t *ma = &el->el_chared.c_macro; c_macro_t *ma = &el->el_chared.c_macro;
#endif /* FIONREAD */ #endif /* FIONREAD */
if (nread == NULL)
nread = &nrb;
*nread = 0; *nread = 0;
if (el->el_flags & NO_TTY) { if (el->el_flags & NO_TTY) {
@ -427,12 +440,13 @@ el_gets(EditLine *el, int *nread)
if (cp[-1] == '\r' || cp[-1] == '\n') if (cp[-1] == '\r' || cp[-1] == '\n')
break; break;
} }
if (num == -1)
el->el_errno = errno;
el->el_line.cursor = el->el_line.lastchar = cp; el->el_line.cursor = el->el_line.lastchar = cp;
*cp = '\0'; *cp = '\0';
if (nread)
*nread = (int)(el->el_line.cursor - el->el_line.buffer); *nread = (int)(el->el_line.cursor - el->el_line.buffer);
return (*nread ? el->el_line.buffer : NULL); goto done;
} }
@ -443,7 +457,7 @@ el_gets(EditLine *el, int *nread)
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs); (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
if (chrs == 0) { if (chrs == 0) {
if (tty_rawmode(el) < 0) { if (tty_rawmode(el) < 0) {
if (nread) errno = 0;
*nread = 0; *nread = 0;
return (NULL); return (NULL);
} }
@ -457,6 +471,7 @@ el_gets(EditLine *el, int *nread)
if (el->el_flags & EDIT_DISABLED) { if (el->el_flags & EDIT_DISABLED) {
char *cp; char *cp;
size_t idx; size_t idx;
if ((el->el_flags & UNBUFFERED) == 0) if ((el->el_flags & UNBUFFERED) == 0)
cp = el->el_line.buffer; cp = el->el_line.buffer;
else else
@ -480,11 +495,13 @@ el_gets(EditLine *el, int *nread)
break; break;
} }
if (num == -1) {
el->el_errno = errno;
}
el->el_line.cursor = el->el_line.lastchar = cp; el->el_line.cursor = el->el_line.lastchar = cp;
*cp = '\0'; *cp = '\0';
if (nread) goto done;
*nread = (int)(el->el_line.cursor - el->el_line.buffer);
return (*nread ? el->el_line.buffer : NULL);
} }
for (num = OKCMD; num == OKCMD;) { /* while still editing this for (num = OKCMD; num == OKCMD;) { /* while still editing this
@ -617,12 +634,17 @@ el_gets(EditLine *el, int *nread)
/* make sure the tty is set up correctly */ /* make sure the tty is set up correctly */
if ((el->el_flags & UNBUFFERED) == 0) { if ((el->el_flags & UNBUFFERED) == 0) {
read_finish(el); read_finish(el);
if (nread) *nread = num != -1 ? num : 0;
*nread = num;
} else { } else {
if (nread) *nread = (int)(el->el_line.lastchar - el->el_line.buffer);
*nread =
(int)(el->el_line.lastchar - el->el_line.buffer);
} }
return (num ? el->el_line.buffer : NULL); done:
if (*nread == 0) {
if (num == -1) {
*nread = -1;
errno = el->el_errno;
}
return NULL;
} else
return el->el_line.buffer;
} }

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $NetBSD: sig.c,v 1.14 2009/02/18 15:04:40 christos Exp $ * $NetBSD: sig.c,v 1.15 2009/02/19 15:20:22 christos Exp $
*/ */
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
@ -73,6 +73,8 @@ sig_handler(int signo)
(void) sigaddset(&nset, signo); (void) sigaddset(&nset, signo);
(void) sigprocmask(SIG_BLOCK, &nset, &oset); (void) sigprocmask(SIG_BLOCK, &nset, &oset);
sel->el_signal->sig_no = signo;
switch (signo) { switch (signo) {
case SIGCONT: case SIGCONT:
tty_rawmode(sel); tty_rawmode(sel);
@ -158,12 +160,12 @@ sig_set(EditLine *el)
struct sigaction osa, nsa; struct sigaction osa, nsa;
nsa.sa_handler = sig_handler; nsa.sa_handler = sig_handler;
nsa.sa_flags = 0;
sigemptyset(&nsa.sa_mask); sigemptyset(&nsa.sa_mask);
(void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset); (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
for (i = 0; sighdl[i] != -1; i++) { for (i = 0; sighdl[i] != -1; i++) {
nsa.sa_flags = SIGINT ? 0 : SA_RESTART;
/* This could happen if we get interrupted */ /* This could happen if we get interrupted */
if (sigaction(sighdl[i], &nsa, &osa) != -1 && if (sigaction(sighdl[i], &nsa, &osa) != -1 &&
osa.sa_handler != sig_handler) osa.sa_handler != sig_handler)

View File

@ -30,7 +30,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* @(#)sig.h 8.1 (Berkeley) 6/4/93 * @(#)sig.h 8.1 (Berkeley) 6/4/93
* $NetBSD: sig.h,v 1.7 2009/02/15 21:25:01 christos Exp $ * $NetBSD: sig.h,v 1.8 2009/02/19 15:20:22 christos Exp $
* $FreeBSD$ * $FreeBSD$
*/ */
@ -61,6 +61,7 @@
typedef struct { typedef struct {
struct sigaction sig_action[ALLSIGSNO]; struct sigaction sig_action[ALLSIGSNO];
sigset_t sig_set; sigset_t sig_set;
volatile sig_atomic_t sig_no;
} *el_signal_t; } *el_signal_t;
protected void sig_end(EditLine*); protected void sig_end(EditLine*);