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
.Dv NULL
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
.Fn el_gets
and must be copied if the data is to be retained.

View File

@ -115,6 +115,7 @@ struct editline {
FILE *el_errfile; /* Stdio stuff */
int el_infd; /* Input file descriptor */
int el_flags; /* Various flags. */
int el_errno; /* Local copy of errno */
coord_t el_cursor; /* Cursor location */
char **el_display; /* Real screen image = what is there */
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;
int num;
el->el_errno = 0;
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);
}
#ifdef KANJI
if ((*ch & 0200)) {
@ -289,14 +292,21 @@ read_char(EditLine *el, char *cp)
ssize_t num_read;
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)
tried = 1;
else {
*cp = '\0';
return (-1);
}
}
return (int)num_read;
}
@ -403,10 +413,13 @@ el_gets(EditLine *el, int *nread)
int num; /* how many chars we have read at NL */
char ch;
int crlf = 0;
int nrb;
#ifdef FIONREAD
c_macro_t *ma = &el->el_chared.c_macro;
#endif /* FIONREAD */
if (nread == NULL)
nread = &nrb;
*nread = 0;
if (el->el_flags & NO_TTY) {
@ -427,12 +440,13 @@ el_gets(EditLine *el, int *nread)
if (cp[-1] == '\r' || cp[-1] == '\n')
break;
}
if (num == -1)
el->el_errno = errno;
el->el_line.cursor = el->el_line.lastchar = cp;
*cp = '\0';
if (nread)
*nread = (int)(el->el_line.cursor - el->el_line.buffer);
return (*nread ? el->el_line.buffer : NULL);
*nread = (int)(el->el_line.cursor - el->el_line.buffer);
goto done;
}
@ -443,8 +457,8 @@ el_gets(EditLine *el, int *nread)
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
if (chrs == 0) {
if (tty_rawmode(el) < 0) {
if (nread)
*nread = 0;
errno = 0;
*nread = 0;
return (NULL);
}
}
@ -457,6 +471,7 @@ el_gets(EditLine *el, int *nread)
if (el->el_flags & EDIT_DISABLED) {
char *cp;
size_t idx;
if ((el->el_flags & UNBUFFERED) == 0)
cp = el->el_line.buffer;
else
@ -480,11 +495,13 @@ el_gets(EditLine *el, int *nread)
break;
}
if (num == -1) {
el->el_errno = errno;
}
el->el_line.cursor = el->el_line.lastchar = cp;
*cp = '\0';
if (nread)
*nread = (int)(el->el_line.cursor - el->el_line.buffer);
return (*nread ? el->el_line.buffer : NULL);
goto done;
}
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 */
if ((el->el_flags & UNBUFFERED) == 0) {
read_finish(el);
if (nread)
*nread = num;
*nread = num != -1 ? num : 0;
} 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
* 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)
@ -73,6 +73,8 @@ sig_handler(int signo)
(void) sigaddset(&nset, signo);
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
sel->el_signal->sig_no = signo;
switch (signo) {
case SIGCONT:
tty_rawmode(sel);
@ -158,12 +160,12 @@ sig_set(EditLine *el)
struct sigaction osa, nsa;
nsa.sa_handler = sig_handler;
nsa.sa_flags = 0;
sigemptyset(&nsa.sa_mask);
(void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
for (i = 0; sighdl[i] != -1; i++) {
nsa.sa_flags = SIGINT ? 0 : SA_RESTART;
/* This could happen if we get interrupted */
if (sigaction(sighdl[i], &nsa, &osa) != -1 &&
osa.sa_handler != sig_handler)

View File

@ -30,7 +30,7 @@
* SUCH DAMAGE.
*
* @(#)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$
*/
@ -61,6 +61,7 @@
typedef struct {
struct sigaction sig_action[ALLSIGSNO];
sigset_t sig_set;
volatile sig_atomic_t sig_no;
} *el_signal_t;
protected void sig_end(EditLine*);