summaryrefslogtreecommitdiffstats
path: root/lib/libedit/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libedit/read.c')
-rw-r--r--lib/libedit/read.c105
1 files changed, 70 insertions, 35 deletions
diff --git a/lib/libedit/read.c b/lib/libedit/read.c
index 0caba5d..ed2b609 100644
--- a/lib/libedit/read.c
+++ b/lib/libedit/read.c
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $NetBSD: read.c,v 1.40 2007/03/01 21:41:45 christos Exp $
+ * $NetBSD: read.c,v 1.52 2009/07/22 15:57:00 christos Exp $
*/
#if !defined(lint) && !defined(SCCSID)
@@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include "el.h"
-#define OKCMD -1
+#define OKCMD -1 /* must be -1! */
private int read__fixio(int, int);
private int read_preread(EditLine *);
@@ -170,7 +170,7 @@ read__fixio(int fd __unused, int e)
return (e ? 0 : -1);
case EINTR:
- return (0);
+ return (-1);
default:
return (-1);
@@ -222,7 +222,7 @@ el_push(EditLine *el, const char *str)
ma->level--;
}
term_beep(el);
- term__flush();
+ term__flush(el);
}
@@ -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)) {
@@ -286,18 +289,25 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
private int
read_char(EditLine *el, char *cp)
{
- int num_read;
+ 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 (num_read);
+ }
+ return (int)num_read;
}
/* read_pop():
@@ -309,8 +319,9 @@ read_pop(c_macro_t *ma)
int i;
el_free(ma->macro[0]);
- for (i = ma->level--; i > 0; i--)
- ma->macro[i - 1] = ma->macro[i];
+ for (i = 0; i < ma->level; i++)
+ ma->macro[i] = ma->macro[i + 1];
+ ma->level--;
ma->offset = 0;
}
@@ -323,7 +334,7 @@ el_getc(EditLine *el, char *cp)
int num_read;
c_macro_t *ma = &el->el_chared.c_macro;
- term__flush();
+ term__flush(el);
for (;;) {
if (ma->level < 0) {
if (!read_preread(el))
@@ -382,7 +393,7 @@ read_prepare(EditLine *el)
re_refresh(el); /* print the prompt */
if (el->el_flags & UNBUFFERED)
- term__flush();
+ term__flush(el);
}
protected void
@@ -402,15 +413,20 @@ 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) {
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);
@@ -424,12 +440,16 @@ el_gets(EditLine *el, int *nread)
if (cp[-1] == '\r' || cp[-1] == '\n')
break;
}
+ if (num == -1) {
+ if (errno == EINTR)
+ cp = el->el_line.buffer;
+ el->el_errno = errno;
+ }
el->el_line.cursor = el->el_line.lastchar = cp;
*cp = '\0';
- if (nread)
- *nread = el->el_line.cursor - el->el_line.buffer;
- return (el->el_line.buffer);
+ *nread = (int)(el->el_line.cursor - el->el_line.buffer);
+ goto done;
}
@@ -440,8 +460,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);
}
}
@@ -454,14 +474,15 @@ 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
cp = el->el_line.lastchar;
- term__flush();
+ 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);
@@ -469,8 +490,6 @@ el_gets(EditLine *el, int *nread)
break;
cp = &el->el_line.buffer[idx];
}
- if (*cp == 4) /* ought to be stty eof */
- break;
cp++;
crlf = cp[-1] == '\r' || cp[-1] == '\n';
if (el->el_flags & UNBUFFERED)
@@ -479,11 +498,15 @@ el_gets(EditLine *el, int *nread)
break;
}
+ if (num == -1) {
+ if (errno == EINTR)
+ cp = el->el_line.buffer;
+ el->el_errno = errno;
+ }
+
el->el_line.cursor = el->el_line.lastchar = cp;
*cp = '\0';
- if (nread)
- *nread = el->el_line.cursor - el->el_line.buffer;
- return (el->el_line.buffer);
+ goto done;
}
for (num = OKCMD; num == OKCMD;) { /* while still editing this
@@ -499,7 +522,13 @@ el_gets(EditLine *el, int *nread)
#endif /* DEBUG_READ */
break;
}
- if ((unsigned int)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
+ if (el->el_errno == EINTR) {
+ el->el_line.buffer[0] = '\0';
+ el->el_line.lastchar =
+ el->el_line.cursor = el->el_line.buffer;
+ break;
+ }
+ if ((unsigned int)cmdnum >= (unsigned int)el->el_map.nfunc) { /* BUG CHECK command */
#ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile,
"ERROR: illegal command from key 0%o\r\n", ch);
@@ -581,7 +610,7 @@ el_gets(EditLine *el, int *nread)
break;
case CC_NEWLINE: /* normal end of line */
- num = el->el_line.lastchar - el->el_line.buffer;
+ num = (int)(el->el_line.lastchar - el->el_line.buffer);
break;
case CC_FATAL: /* fatal error, reset to known state */
@@ -602,7 +631,7 @@ el_gets(EditLine *el, int *nread)
"*** editor ERROR ***\r\n\n");
#endif /* DEBUG_READ */
term_beep(el);
- term__flush();
+ term__flush(el);
break;
}
el->el_state.argument = 1;
@@ -612,15 +641,21 @@ el_gets(EditLine *el, int *nread)
break;
}
- term__flush(); /* flush any buffered output */
+ term__flush(el); /* flush any buffered output */
/* 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 = 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;
}
OpenPOWER on IntegriCloud