summaryrefslogtreecommitdiffstats
path: root/lib/libedit
diff options
context:
space:
mode:
authorpfg <pfg@FreeBSD.org>2012-07-11 22:20:19 +0000
committerpfg <pfg@FreeBSD.org>2012-07-11 22:20:19 +0000
commitea0d3f8feef5d5dccadf4649dcda2769dc1ad173 (patch)
tree420574dfcf4d37b2a2cebc7c381010ef9989a197 /lib/libedit
parent676e6cd9af77f9583b012de4cc5037a3e7fd503e (diff)
downloadFreeBSD-src-ea0d3f8feef5d5dccadf4649dcda2769dc1ad173.zip
FreeBSD-src-ea0d3f8feef5d5dccadf4649dcda2769dc1ad173.tar.gz
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
Diffstat (limited to 'lib/libedit')
-rw-r--r--lib/libedit/editline.35
-rw-r--r--lib/libedit/el.h1
-rw-r--r--lib/libedit/read.c56
-rw-r--r--lib/libedit/sig.c6
-rw-r--r--lib/libedit/sig.h3
5 files changed, 51 insertions, 20 deletions
diff --git a/lib/libedit/editline.3 b/lib/libedit/editline.3
index dd4c874..fe58321 100644
--- a/lib/libedit/editline.3
+++ b/lib/libedit/editline.3
@@ -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.
diff --git a/lib/libedit/el.h b/lib/libedit/el.h
index 8d0d152..67d01ff 100644
--- a/lib/libedit/el.h
+++ b/lib/libedit/el.h
@@ -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 */
diff --git a/lib/libedit/read.c b/lib/libedit/read.c
index ea40e50..7d7f54b 100644
--- a/lib/libedit/read.c
+++ b/lib/libedit/read.c
@@ -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;
}
diff --git a/lib/libedit/sig.c b/lib/libedit/sig.c
index 218a32e..e48dbef 100644
--- a/lib/libedit/sig.c
+++ b/lib/libedit/sig.c
@@ -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)
diff --git a/lib/libedit/sig.h b/lib/libedit/sig.h
index 8773ddc..7e38100 100644
--- a/lib/libedit/sig.h
+++ b/lib/libedit/sig.h
@@ -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*);
OpenPOWER on IntegriCloud