svn commit: r238378 - head/lib/libedit

Pedro F. Giffuni pfg at FreeBSD.org
Wed Jul 11 22:20:20 UTC 2012


Author: pfg
Date: Wed Jul 11 22:20:19 2012
New Revision: 238378
URL: http://svn.freebsd.org/changeset/base/238378

Log:
  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

Modified:
  head/lib/libedit/editline.3
  head/lib/libedit/el.h
  head/lib/libedit/read.c
  head/lib/libedit/sig.c
  head/lib/libedit/sig.h

Modified: head/lib/libedit/editline.3
==============================================================================
--- head/lib/libedit/editline.3	Wed Jul 11 22:17:58 2012	(r238377)
+++ head/lib/libedit/editline.3	Wed Jul 11 22:20:19 2012	(r238378)
@@ -162,6 +162,11 @@ is modified to contain the number of cha
 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.

Modified: head/lib/libedit/el.h
==============================================================================
--- head/lib/libedit/el.h	Wed Jul 11 22:17:58 2012	(r238377)
+++ head/lib/libedit/el.h	Wed Jul 11 22:20:19 2012	(r238378)
@@ -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 */

Modified: head/lib/libedit/read.c
==============================================================================
--- head/lib/libedit/read.c	Wed Jul 11 22:17:58 2012	(r238377)
+++ head/lib/libedit/read.c	Wed Jul 11 22:20:19 2012	(r238378)
@@ -235,9 +235,12 @@ read_getcmd(EditLine *el, el_action_t *c
 	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;
 }

Modified: head/lib/libedit/sig.c
==============================================================================
--- head/lib/libedit/sig.c	Wed Jul 11 22:17:58 2012	(r238377)
+++ head/lib/libedit/sig.c	Wed Jul 11 22:20:19 2012	(r238378)
@@ -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)

Modified: head/lib/libedit/sig.h
==============================================================================
--- head/lib/libedit/sig.h	Wed Jul 11 22:17:58 2012	(r238377)
+++ head/lib/libedit/sig.h	Wed Jul 11 22:20:19 2012	(r238378)
@@ -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*);


More information about the svn-src-all mailing list