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:
parent
00c43e0ca4
commit
c4fff9dd3a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=238378
@ -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.
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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*);
|
||||||
|
Loading…
Reference in New Issue
Block a user