NetBSD Problem Report #46935

From www@NetBSD.org  Mon Sep 10 19:59:08 2012
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
	by www.NetBSD.org (Postfix) with ESMTP id 5B43263DC4E
	for <gnats-bugs@gnats.NetBSD.org>; Mon, 10 Sep 2012 19:59:08 +0000 (UTC)
Message-Id: <20120910195907.9319063B9BC@www.NetBSD.org>
Date: Mon, 10 Sep 2012 19:59:07 +0000 (UTC)
From: sdaoden@gmail.com
Reply-To: sdaoden@gmail.com
To: gnats-bugs@NetBSD.org
Subject: editline(3) (libedit): faulty errno handling, faulty reuse of val in wrong context
X-Send-Pr-Version: www-1.0

>Number:         46935
>Category:       lib
>Synopsis:       editline(3) (libedit): faulty errno handling, faulty reuse of val in wrong context
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Sep 10 20:00:01 +0000 2012
>Last-Modified:  Thu Sep 13 18:00:04 +0000 2012
>Originator:     Steffen Nurpmeso
>Release:        netbsd-6-base
>Organization:
>Environment:
None - seen on HEAD and netbsd-6-base
>Description:
While i had the chance to work on FreeBSD PR bin/169773 [1] some
bugs in read.c were revealed.
Now that i've looked at the NetBSD version there seem to be rather
the same problem(s).

[1] http://www.freebsd.org/cgi/query-pr.cgi?pr=169773&cat=
>How-To-Repeat:
Look at the source.
>Fix:
Diff against netbsd-6-base as of 2012-08-31.
The EILSEQ case may not be correct (in respect to value).
I'm not running NetBSD (for real) at the moment, so someone
with a glue should look at that.  It has not been tested,
not even compiled (due to above reason).

diff --git a/src/lib/libedit/read.c b/src/lib/libedit/read.c
index 8fcf6eb..38d586c 100644
--- a/src/lib/libedit/read.c
+++ b/src/lib/libedit/read.c
@@ -321,6 +321,7 @@ read_char(EditLine *el, Char *cp)
  again:
 	el->el_signal->sig_no = 0;
 	while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) {
+		int e = errno;
 		switch (el->el_signal->sig_no) {
 		case SIGCONT:
 			FUN(el,set)(el, EL_REFRESH);
@@ -331,9 +332,10 @@ read_char(EditLine *el, Char *cp)
 		default:
 			break;
 		}
-		if (!tried && read__fixio(el->el_infd, errno) == 0)
+		if (!tried && read__fixio(el->el_infd, e) == 0)
 			tried = 1;
 		else {
+			errno = e;
 			*cp = '\0';
 			return -1;
 		}
@@ -347,6 +349,7 @@ read_char(EditLine *el, Char *cp)
 		if ((bytes = ct_mbtowc(cp, cbuf, cbp)) == -1) {
 			ct_mbtowc_reset;
 			if (cbp >= MB_LEN_MAX) { /* "shouldn't happen" */
+				errno = EILSEQ;
 				*cp = '\0';
 				return -1;
 			}
@@ -427,6 +430,8 @@ FUN(el,getc)(EditLine *el, Char *cp)
 	(void) fprintf(el->el_errfile, "Reading a character\n");
 #endif /* DEBUG_READ */
 	num_read = (*el->el_read.read_char)(el, cp);
+	if (num_read < 0)
+		el->el_errno = errno;
 #ifdef WIDECHAR
 	if (el->el_flags & NARROW_READ)
 		*cp = *(char *)(void *)cp;
@@ -572,6 +577,7 @@ FUN(el,gets)(EditLine *el, int *nread)
 #endif /* DEBUG_EDIT */
 		/* if EOF or error */
 		if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
+			num = -1;
 #ifdef DEBUG_READ
 			(void) fprintf(el->el_errfile,
 			    "Returning from el_gets %d\n", num);

>Audit-Trail:
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/46935 CVS commit: src/lib/libedit
Date: Mon, 10 Sep 2012 16:53:18 -0400

 Module Name:	src
 Committed By:	christos
 Date:		Mon Sep 10 20:53:18 UTC 2012

 Modified Files:
 	src/lib/libedit: read.c

 Log Message:
 PR/46935: Steffen Nurpmeso: editline(3) (libedit): faulty errno handling,
 faulty reuse of val in wrong context


 To generate a diff of this commit:
 cvs rdiff -u -r1.67 -r1.68 src/lib/libedit/read.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
To: gnats-bugs@NetBSD.org
Cc: netbsd-bugs@netbsd.org, lib-bug-people@netbsd.org,
 gnats-admin@netbsd.org
Subject: Re: PR/46935 CVS commit: src/lib/libedit
Date: Tue, 11 Sep 2012 13:15:06 +0200

 "Christos Zoulas" <christos@netbsd.org> wrote:

  |The following reply was made to PR lib/46935; it has been noted by GNATS.
  |
  |From: "Christos Zoulas" <christos@netbsd.org>
  |To: gnats-bugs@gnats.NetBSD.org
  |Cc: 
  |Subject: PR/46935 CVS commit: src/lib/libedit
  |Date: Mon, 10 Sep 2012 16:53:18 -0400
  |
  | Module Name:	src
  | Committed By:	christos
  | Date:		Mon Sep 10 20:53:18 UTC 2012
  | 
  | Modified Files:
  | 	src/lib/libedit: read.c
  | 
  | Log Message:
  | PR/46935: Steffen Nurpmeso: editline(3) (libedit): faulty errno handling,
  | faulty reuse of val in wrong context
  | 
  | 
  | To generate a diff of this commit:
  | cvs rdiff -u -r1.67 -r1.68 src/lib/libedit/read.c
  | 
  | Please note that diffs are not public domain; they are subject to the
  | copyright notices on the relevant files.
  | 

 I'm sorry but i have forgotten some bits as below.
 (errno already set by called fun, *num* has to be mapped.)

 --steffen

     Forgotten bits of errno codeflow
 ---
  src/lib/libedit/read.c |    3 +--
  1 files changed, 1 insertions(+), 2 deletions(-)

 diff --git a/src/lib/libedit/read.c b/src/lib/libedit/read.c
 index 38d586c..7986394 100644
 --- a/src/lib/libedit/read.c
 +++ b/src/lib/libedit/read.c
 @@ -245,8 +245,7 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
  	el->el_errno = 0;
  	do {
  		if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */
 -			el->el_errno = num == 0 ? 0 : errno;
 -			return num;
 +			return (num < 0 ? 1 : 0);
  		}

  #ifdef	KANJI

From: christos@zoulas.com (Christos Zoulas)
To: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>, gnats-bugs@NetBSD.org
Cc: netbsd-bugs@netbsd.org, lib-bug-people@netbsd.org, 
	gnats-admin@netbsd.org
Subject: Re: PR/46935 CVS commit: src/lib/libedit
Date: Tue, 11 Sep 2012 07:55:15 -0400

 On Sep 11,  1:15pm, sdaoden@gmail.com (Steffen "Daode" Nurpmeso) wrote:
 -- Subject: Re: PR/46935 CVS commit: src/lib/libedit

 | I'm sorry but i have forgotten some bits as below.
 | (errno already set by called fun, *num* has to be mapped.)
 | 
 | --steffen
 | 
 |     Forgotten bits of errno codeflow
 | ---
 |  src/lib/libedit/read.c |    3 +--
 |  1 files changed, 1 insertions(+), 2 deletions(-)
 | 
 | diff --git a/src/lib/libedit/read.c b/src/lib/libedit/read.c
 | index 38d586c..7986394 100644
 | --- a/src/lib/libedit/read.c
 | +++ b/src/lib/libedit/read.c
 | @@ -245,8 +245,7 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
 |  	el->el_errno = 0;
 |  	do {
 |  		if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */
 | -			el->el_errno = num == 0 ? 0 : errno;
 | -			return num;
 | +			return (num < 0 ? 1 : 0);
 |  		}

 That is supposed to return a CMD; shouldn't it return ED_END_OF_FILE or
 something?

 christos

From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
To: gnats-bugs@NetBSD.org
Cc: netbsd-bugs@netbsd.org, lib-bug-people@netbsd.org,
 gnats-admin@netbsd.org
Subject: Re: PR/46935 CVS commit: src/lib/libedit
Date: Tue, 11 Sep 2012 14:23:57 +0200

 christos@zoulas.com (Christos Zoulas) wrote:

  |The following reply was made to PR lib/46935; it has been noted by GNATS.
  |
  |From: christos@zoulas.com (Christos Zoulas)
  |To: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>, gnats-bugs@NetBSD.org
  |Cc: netbsd-bugs@netbsd.org, lib-bug-people@netbsd.org, 
  |	gnats-admin@netbsd.org
  |Subject: Re: PR/46935 CVS commit: src/lib/libedit
  |Date: Tue, 11 Sep 2012 07:55:15 -0400
  |
  | On Sep 11,  1:15pm, sdaoden@gmail.com (Steffen "Daode" Nurpmeso) wrote:
  | -- Subject: Re: PR/46935 CVS commit: src/lib/libedit
  | 
  || I'm sorry but i have forgotten some bits as below.
  || (errno already set by called fun, *num* has to be mapped.)
  || 
  || --steffen
  || 
  ||     Forgotten bits of errno codeflow
  || ---
  ||  src/lib/libedit/read.c |    3 +--
  ||  1 files changed, 1 insertions(+), 2 deletions(-)
  || 
  || diff --git a/src/lib/libedit/read.c b/src/lib/libedit/read.c
  || index 38d586c..7986394 100644
  || --- a/src/lib/libedit/read.c
  || +++ b/src/lib/libedit/read.c
  || @@ -245,8 +245,7 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, Char \
  |. *ch)
  ||  	el->el_errno = 0;
  ||  	do {
  ||  		if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */
  || -			el->el_errno = num == 0 ? 0 : errno;
  || -			return num;
  || +			return (num < 0 ? 1 : 0);
  ||  		}
  | 
  | That is supposed to return a CMD; shouldn't it return ED_END_OF_FILE or
  | something?
  | 
  | christos

 You're right, simply returning some value !OKCMD seems to be
 sufficient.

 --steffen

     Forgotten bits of errno codeflow
 ---
  src/lib/libedit/read.c |    5 ++---
  1 files changed, 2 insertions(+), 3 deletions(-)

 diff --git a/src/lib/libedit/read.c b/src/lib/libedit/read.c
 index 38d586c..a1ed1c6 100644
 --- a/src/lib/libedit/read.c
 +++ b/src/lib/libedit/read.c
 @@ -233,7 +233,7 @@ FUN(el,push)(EditLine *el, const Char *str)


  /* read_getcmd():
 - *	Return next command from the input stream.
 + *	Get next command from the input stream, return OKCMD on success.
   *	Character values > 255 are not looked up in the map, but inserted.
   */
  private int
 @@ -245,8 +245,7 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
  	el->el_errno = 0;
  	do {
  		if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */
 -			el->el_errno = num == 0 ? 0 : errno;
 -			return num;
 +			return 0;
  		}

  #ifdef	KANJI

From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
To: gnats-bugs@NetBSD.org
Cc: netbsd-bugs@netbsd.org, lib-bug-people@netbsd.org,
 gnats-admin@netbsd.org
Subject: Re: PR/46935 CVS commit: src/lib/libedit
Date: Tue, 11 Sep 2012 14:59:28 +0200

 Steffen "Daode" Nurpmeso <sdaoden@gmail.com> wrote:

  |The following reply was made to PR lib/46935; it has been noted by GNATS.
  [.]
  |  | That is supposed to return a CMD; shouldn't it return ED_END_OF_FILE or
  |  | something?
  |  | 
  |  | christos
  | 
  | You're right, simply returning some value !OKCMD seems to be
  | sufficient.

 Uuh, no, it's much more complicated than that.

  | --steffen

 Yes, i'm afraid so :)

From: christos@zoulas.com (Christos Zoulas)
To: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>, gnats-bugs@NetBSD.org
Cc: netbsd-bugs@netbsd.org, lib-bug-people@netbsd.org, 
	gnats-admin@netbsd.org
Subject: Re: PR/46935 CVS commit: src/lib/libedit
Date: Tue, 11 Sep 2012 09:41:43 -0400

 On Sep 11,  2:59pm, sdaoden@gmail.com (Steffen "Daode" Nurpmeso) wrote:
 -- Subject: Re: PR/46935 CVS commit: src/lib/libedit

 | Steffen "Daode" Nurpmeso <sdaoden@gmail.com> wrote:
 | 
 |  |The following reply was made to PR lib/46935; it has been noted by GNATS.
 |  [.]
 |  |  | That is supposed to return a CMD; shouldn't it return ED_END_OF_FILE or
 |  |  | something?
 |  |  | 
 |  |  | christos
 |  | 
 |  | You're right, simply returning some value !OKCMD seems to be
 |  | sufficient.
 | 
 | Uuh, no, it's much more complicated than that.

 Ok, let me think about it then :-)

 christos

From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
To: gnats-bugs@NetBSD.org
Cc: netbsd-bugs@netbsd.org, lib-bug-people@netbsd.org,
 gnats-admin@netbsd.org
Subject: Re: PR/46935 CVS commit: src/lib/libedit
Date: Tue, 11 Sep 2012 16:48:38 +0200

 christos@zoulas.com (Christos Zoulas) wrote:

  |The following reply was made to PR lib/46935; it has been noted by GNATS.
  |
  |From: christos@zoulas.com (Christos Zoulas)
  |To: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>, gnats-bugs@NetBSD.org
  |Cc: netbsd-bugs@netbsd.org, lib-bug-people@netbsd.org, 
  |	gnats-admin@netbsd.org
  |Subject: Re: PR/46935 CVS commit: src/lib/libedit
  |Date: Tue, 11 Sep 2012 09:41:43 -0400
  |
  | On Sep 11,  2:59pm, sdaoden@gmail.com (Steffen "Daode" Nurpmeso) wrote:
  | -- Subject: Re: PR/46935 CVS commit: src/lib/libedit
  | 
  || Steffen "Daode" Nurpmeso <sdaoden@gmail.com> wrote:
  || 
  ||  |The following reply was made to PR lib/46935; it has been noted by \
  |. GNATS.
  ||  [.]
  ||  |  | That is supposed to return a CMD; shouldn't it return \
  |. ED_END_OF_FILE or
  ||  |  | something?
  ||  |  | 
  ||  |  | christos
  ||  | 
  ||  | You're right, simply returning some value !OKCMD seems to be
  ||  | sufficient.
  || 
  || Uuh, no, it's much more complicated than that.
  | 
  | Ok, let me think about it then :-)
  | 
  | christos

 I have this version running (on FreeBSD..) at the moment, and it
 seems to work (i'm having READ_RESTART set here - any chance on
 that?).

 First el_getc() now *always* sets el_errno so that read_getcmd()
 can definitely avoid doing so.

 I think v1.69 still has the problem that the loop requires a new
 stop condition (*num* is looked at in the switch, though the value
 is effectively somewhat meaningless).
 So i've introduced a new command state enum which should get
 rid of any ambiguities that may arise from missing the complete
 picture :), and which is used as a break-off command in the loop.

 Note that i'm not sure at all about the CC_EOF case; it yet looked
 at num==-1, but how can that happen there?  Anyway - no more.

 This patch applies to v1.69 only with fuzziness, but it is a bit
 chaotic here at the moment..

 What do you think about that?

 --steffen

 --- read.c.orig	2012-09-11 15:51:03.000000000 +0200
 +++ read.c	2012-09-11 15:51:03.000000000 +0200
 @@ -52,13 +52,17 @@ __RCSID("$NetBSD: read.c,v 1.69 2012/09/
  #include <limits.h>
  #include "el.h"

 -#define OKCMD	-1	/* must be -1! */
 -
 -private int	read__fixio(int, int);
 -private int	read_preread(EditLine *);
 -private int	read_char(EditLine *, Char *);
 -private int	read_getcmd(EditLine *, el_action_t *, Char *);
 -private void	read_pop(c_macro_t *);
 +enum rcmd {
 +	OKCMD	= -1,
 +	EOFCMD	= 0,
 +	ERRCMD	= 1
 +};
 +
 +private int		read__fixio(int, int);
 +private int		read_preread(EditLine *);
 +private int		read_char(EditLine *, Char *);
 +private enum rcmd	read_getcmd(EditLine *, el_action_t *, Char *);
 +private void		read_pop(c_macro_t *);

  /* read_init():
   *	Initialize the read stuff
 @@ -233,10 +237,10 @@ FUN(el,push)(EditLine *el, const Char *s


  /* read_getcmd():
 - *	Get next command from the input stream, return OKCMD on success.
 + *	Get next command from the input stream.
   *	Character values > 255 are not looked up in the map, but inserted.
   */
 -private int
 +private enum rcmd
  read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
  {
  	el_action_t cmd;
 @@ -245,8 +249,7 @@ read_getcmd(EditLine *el, el_action_t *c
  	el->el_errno = 0;
  	do {
  		if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */
 -			el->el_errno = num == 0 ? 0 : errno;
 -			return 0;	/* not OKCMD */
 +			return (num < 0 ? ERRCMD : EOFCMD);
  		}

  #ifdef	KANJI
 @@ -430,14 +435,13 @@ FUN(el,getc)(EditLine *el, Char *cp)
  	(void) fprintf(el->el_errfile, "Reading a character\n");
  #endif /* DEBUG_READ */
  	num_read = (*el->el_read.read_char)(el, cp);
 -	if (num_read < 0)
 -		el->el_errno = errno;
 +	el->el_errno = (num_read < 0) ? errno : 0;
  #ifdef WIDECHAR
  	if (el->el_flags & NARROW_READ)
  		*cp = *(char *)(void *)cp;
  #endif
  #ifdef DEBUG_READ
 -	(void) fprintf(el->el_errfile, "Got it %c\n", *cp);
 +	(void) fprintf(el->el_errfile, "Got <%c> (return %d)\n", *cp, num_read);
  #endif /* DEBUG_READ */
  	return num_read;
  }
 @@ -570,26 +574,32 @@ FUN(el,gets)(EditLine *el, int *nread)
  		goto noedit;
  	}

 -	for (num = OKCMD; num == OKCMD;) {	/* while still editing this
 -						 * line */
 +	/* While still editing this line */
 +	for (num = 0;; num = 0) {
 +		enum rcmd rcmd;
  #ifdef DEBUG_EDIT
  		read_debug(el);
  #endif /* DEBUG_EDIT */
 -		/* if EOF or error */
 -		if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
 -			num = -1;
 +		if ((rcmd = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
 +			if (rcmd == ERRCMD) {
 +				num = -1;
 +				if (el->el_errno == EINTR) {
 +#ifdef DEBUG_READ
 +					(void) fprintf(el->el_errfile,
 +					    "Returning from el_gets due to EINTR\n");
 +#endif /* DEBUG_READ */
 +					el->el_line.buffer[0] = '\0';
 +					el->el_line.lastchar =
 +					    el->el_line.cursor = el->el_line.buffer;
 +					break;
 +				}
 +			}
  #ifdef DEBUG_READ
  			(void) fprintf(el->el_errfile,
  			    "Returning from el_gets %d\n", num);
  #endif /* DEBUG_READ */
  			break;
  		}
 -		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,
 @@ -662,9 +672,10 @@ FUN(el,gets)(EditLine *el, int *nread)
  			continue;	/* keep going... */

  		case CC_EOF:	/* end of file typed */
 +			rcmd = EOFCMD;
  			if ((el->el_flags & UNBUFFERED) == 0)
  				num = 0;
 -			else if (num == -1) {
 +			else {
  				*el->el_line.lastchar++ = CONTROL('d');
  				el->el_line.cursor = el->el_line.lastchar;
  				num = 1;
 @@ -672,6 +683,7 @@ FUN(el,gets)(EditLine *el, int *nread)
  			break;

  		case CC_NEWLINE:	/* normal end of line */
 +			rcmd = EOFCMD;
  			num = (int)(el->el_line.lastchar - el->el_line.buffer);
  			break;

 @@ -711,6 +711,8 @@ FUN(el,gets)(EditLine *el, int *nread)
  		el->el_chared.c_vcmd.action = NOP;
  		if (el->el_flags & UNBUFFERED)
  			break;
 +		if (rcmd != OKCMD)
 +			break;
  	}

  	terminal__flush(el);		/* flush any buffered output */

From: christos@zoulas.com (Christos Zoulas)
To: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>, gnats-bugs@NetBSD.org
Cc: netbsd-bugs@netbsd.org, lib-bug-people@netbsd.org, 
	gnats-admin@netbsd.org
Subject: Re: PR/46935 CVS commit: src/lib/libedit
Date: Tue, 11 Sep 2012 21:11:00 -0400

 On Sep 11,  4:48pm, sdaoden@gmail.com (Steffen "Daode" Nurpmeso) wrote:
 -- Subject: Re: PR/46935 CVS commit: src/lib/libedit

 | I have this version running (on FreeBSD..) at the moment, and it
 | seems to work (i'm having READ_RESTART set here - any chance on
 | that?).
 | 
 | First el_getc() now *always* sets el_errno so that read_getcmd()
 | can definitely avoid doing so.
 | 
 | I think v1.69 still has the problem that the loop requires a new
 | stop condition (*num* is looked at in the switch, though the value
 | is effectively somewhat meaningless).
 | So i've introduced a new command state enum which should get
 | rid of any ambiguities that may arise from missing the complete
 | picture :), and which is used as a break-off command in the loop.
 | 
 | Note that i'm not sure at all about the CC_EOF case; it yet looked
 | at num==-1, but how can that happen there?  Anyway - no more.
 | 
 | This patch applies to v1.69 only with fuzziness, but it is a bit
 | chaotic here at the moment..
 | 
 | What do you think about that?

 I like the enum clarity, but I am not sure about removing the EINTR
 code. I also have to check the EOF logic too. Test it some more, and
 I need to find some time here to test it myself. I bit busy since I
 just came back from vacation...

 christos

From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
To: christos@zoulas.com (Christos Zoulas)
Cc: netbsd-bugs@netbsd.org, lib-bug-people@netbsd.org,
 gnats-bugs@NetBSD.org, gnats-admin@netbsd.org
Subject: Re: PR/46935 CVS commit: src/lib/libedit
Date: Thu, 13 Sep 2012 19:54:56 +0200

 This is a multi-part message in MIME format.

 --=_50521df0.GUGyPhvl+wFO2fsogriKx2qrb0wBUv14DwebV0W/v0GtimcZ
 Content-Type: text/plain; charset=us-ascii
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline

 Replying to myself, Google has rejected my mail because of
 a libedit-test.tar.gz attachment:

   |smtp-server: 552-5.7.0 Our system detected an illegal attachment on your message. Please
   |smtp-server: 552-5.7.0 visit http://support.google.com/mail/bin/answer.py?answer=6590 to
   |smtp-server: 552 5.7.0 review our attachment guidelines.

 This time attaching the same stuff as a shell archive with
 compressed members.
 Thanks!

  |christos@zoulas.com (Christos Zoulas) wrote:
  |
  ||On Sep 11,  4:48pm, sdaoden@gmail.com (Steffen "Daode" Nurpmeso) wrote:
  ||-- Subject: Re: PR/46935 CVS commit: src/lib/libedit
  ||
  | [.]
  ||| What do you think about that?
  |
  |First i have to say that i hope i have finally encapsulated
  |el_errno=0 in el_getc() properly.
  |
  |And that this iteration was entirely done on NetBSD 6 RC1 using
  |a libedit from HEAD (and terminfo from 6).
  |
  ||I like the enum clarity[.]
  |
  |I've chosen a different name for the enum -- here there was
  |a "rcmd" name clash.
  |
  ||[.], but I am not sure about removing the EINTR
  |
  |Now that read_getcmd() fails with ERRCMD on error only EINTR can
  |only be tested inside that conditional.  Otherwise my patch would
  |still not be complete.
  |
  ||code. I also have to check the EOF logic too. Test it some more, and
  |
  |I'm pretty sure now that removing the ==-1 case was correct.
  |I don't know what it was there for, but effectively it tests
  |==OKCMD until now, which is of course wrong (since always true).
  |
  ||I need to find some time here to test it myself. I bit busy since I
  |
  |I'll attach the super simple test i've used (simply copying over
  |FreeBSD sh(1) code less proper buffer handling), including
  |a read.c.debug file which pimps up regular read.c by an immense
  |amount of debug fprintf(3) statements, which makes it easier to
  |prove that this patch is now really correct.  (What i hope).

 [This is libedit-test.shar now..]

  ||just came back from vacation...
  |
  |AH - for us i hope we can go down south soon, and finally finally
  |finally..
  |And also to were you came from -- i love this fantastic light in
  |Greece, and the colours, through it..  It's so beautiful.
  |Unbelievable that you left that by choice!!
  |[Flabbergasted for a moment]
  |
  |Hmm.  Different to the Colossus of Rhodes the Colossa of New York
  |is still standing; even without Norah Jones actually being
  |around!!; that that can happen..  But i don't know, i never left
  |Europe myself..  An american uncle, that's all.  Traffic pollutes
  |right..  Solar airplanes maybe, but they are too slow for the
  |people.
  |
  |Anyway.  Good to hear that you are recuperated, because i have
  |founf two more problems in editline(3) :-)
  |
  |- UNBUFFERED always appends to the buffer.
  |  That behaviour is not documented, and i was surprised to detect
  |  that during testing.  Is this really the desired behaviour?
  |
  |- There is no safety-belt against overflowing the line buffer.
  |  Wether UNBUFFERED or not, nothing prevents you from that (though
  |  of course el_gets() reset it upon entry except in the UNBUFFERED
  |  case), and it is only detected if DEBUG_EDIT is #define'd.
  |  However, the .limit is actively set in some files which i have
  |  not looked at yet, so i left that off.
  |  Maybe a different PR?  And how to solve?
  |
  ||christos
  |
  |'Hope this patch does it!
  |Ciao,
  |
  |--steffen

 --=_50521df0.GUGyPhvl+wFO2fsogriKx2qrb0wBUv14DwebV0W/v0GtimcZ
 Content-Type: text/plain;
  charset=us-ascii
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="libedit-read.diff"

 --- read.c.orig	2012-09-12 23:33:16.000000000 +0200
 +++ read.c	2012-09-13 18:47:12.000000000 +0200
 @@ -52,13 +52,23 @@ __RCSID("$NetBSD: read.c,v 1.69 2012/09/
  #include <limits.h>
  #include "el.h"

 -#define OKCMD	-1	/* must be -1! */
 +#ifdef WIDECHAR
 +# define SCNV	"%ls"
 +#else
 +# define SCNV	"%s"
 +#endif

 -private int	read__fixio(int, int);
 -private int	read_preread(EditLine *);
 -private int	read_char(EditLine *, Char *);
 -private int	read_getcmd(EditLine *, el_action_t *, Char *);
 -private void	read_pop(c_macro_t *);
 +enum cmdstate {
 +	OKCMD	= -1,
 +	EOFCMD	= 0,
 +	ERRCMD	= 1
 +};
 +
 +private int		read__fixio(int, int);
 +private int		read_preread(EditLine *);
 +private int		read_char(EditLine *, Char *);
 +private enum cmdstate	read_getcmd(EditLine *, el_action_t *, Char *);
 +private void		read_pop(c_macro_t *);

  /* read_init():
   *	Initialize the read stuff
 @@ -172,9 +182,6 @@ read__fixio(int fd __attribute__((__unus
  #endif /* TRY_AGAIN */
  		return e ? 0 : -1;

 -	case EINTR:
 -		return 0;
 -
  	default:
  		return -1;
  	}
 @@ -233,20 +240,18 @@ FUN(el,push)(EditLine *el, const Char *s


  /* read_getcmd():
 - *	Get next command from the input stream, return OKCMD on success.
 + *	Get next command from the input stream.
   *	Character values > 255 are not looked up in the map, but inserted.
   */
 -private int
 +private enum cmdstate
  read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
  {
  	el_action_t cmd;
  	int num;

 -	el->el_errno = 0;
  	do {
  		if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */
 -			el->el_errno = num == 0 ? 0 : errno;
 -			return 0;	/* not OKCMD */
 +			return (num < 0 ? ERRCMD : EOFCMD);
  		}

  #ifdef	KANJI
 @@ -318,27 +323,27 @@ read_char(EditLine *el, Char *cp)
  	size_t cbp = 0;
  	int bytes = 0;

 - again:
  	el->el_signal->sig_no = 0;
 + again:
  	while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) {
  		int e = errno;
 -		switch (el->el_signal->sig_no) {
 -		case SIGCONT:
 -			FUN(el,set)(el, EL_REFRESH);
 -			/*FALLTHROUGH*/
 -		case SIGWINCH:
 -			sig_set(el);
 +		if (e == EINTR) {
 +			switch (el->el_signal->sig_no) {
 +			case SIGCONT:
 +				FUN(el,set)(el, EL_REFRESH);
 +				/*FALLTHROUGH*/
 +			case SIGWINCH:
 +				sig_set(el);
 +				el->el_signal->sig_no = 0;
 +				goto again;
 +			default:
 +				break;
 +			}
 +		} else if (! tried++ && read__fixio(el->el_infd, e) == 0)
  			goto again;
 -		default:
 -			break;
 -		}
 -		if (!tried && read__fixio(el->el_infd, e) == 0)
 -			tried = 1;
 -		else {
 -			errno = e;
 -			*cp = '\0';
 -			return -1;
 -		}
 +		errno = e;
 +		*cp = '\0';
 +		return -1;
  	}

  #ifdef WIDECHAR
 @@ -394,6 +399,7 @@ FUN(el,getc)(EditLine *el, Char *cp)
  {
  	int num_read;
  	c_macro_t *ma = &el->el_chared.c_macro;
 +	el->el_errno = 0;

  	terminal__flush(el);
  	for (;;) {
 @@ -437,7 +443,7 @@ FUN(el,getc)(EditLine *el, Char *cp)
  		*cp = *(char *)(void *)cp;
  #endif
  #ifdef DEBUG_READ
 -	(void) fprintf(el->el_errfile, "Got it %c\n", *cp);
 +	(void) fprintf(el->el_errfile, "Got <%c> (return %d)\n", *cp, num_read);
  #endif /* DEBUG_READ */
  	return num_read;
  }
 @@ -570,26 +576,33 @@ FUN(el,gets)(EditLine *el, int *nread)
  		goto noedit;
  	}

 -	for (num = OKCMD; num == OKCMD;) {	/* while still editing this
 -						 * line */
 +	/* The command drive input loop */
 +	for (num = 0;;) {
 +		enum cmdstate cmdstate;
  #ifdef DEBUG_EDIT
  		read_debug(el);
  #endif /* DEBUG_EDIT */
 -		/* if EOF or error */
 -		if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
 -			num = -1;
 +		if ((cmdstate = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
 +			if (cmdstate == ERRCMD) {
 +				num = -1;
 +				if (el->el_errno == EINTR) {
 +#ifdef DEBUG_READ
 +					(void) fprintf(el->el_errfile,
 +					    "Return from el_gets due EINTR\n");
 +#endif /* DEBUG_READ */
 +					el->el_line.buffer[0] = '\0';
 +					el->el_line.lastchar =
 +					    el->el_line.cursor =
 +					    el->el_line.buffer;
 +					break;
 +				}
 +			}
  #ifdef DEBUG_READ
  			(void) fprintf(el->el_errfile,
  			    "Returning from el_gets %d\n", num);
  #endif /* DEBUG_READ */
  			break;
  		}
 -		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,
 @@ -606,7 +619,7 @@ FUN(el,gets)(EditLine *el, int *nread)
  					break;
  			if (b->name)
  				(void) fprintf(el->el_errfile,
 -				    "Executing %s\n", b->name);
 +				    "Executing " SCNV "\n", b->name);
  			else
  				(void) fprintf(el->el_errfile,
  				    "Error command = %d\n", cmdnum);
 @@ -662,16 +675,17 @@ FUN(el,gets)(EditLine *el, int *nread)
  			continue;	/* keep going... */

  		case CC_EOF:	/* end of file typed */
 +			cmdstate = EOFCMD;
  			if ((el->el_flags & UNBUFFERED) == 0)
  				num = 0;
 -			else if (num == -1) {
 +			else {
  				*el->el_line.lastchar++ = CONTROL('d');
  				el->el_line.cursor = el->el_line.lastchar;
 -				num = 1;
  			}
  			break;

  		case CC_NEWLINE:	/* normal end of line */
 +			cmdstate = EOFCMD;
  			num = (int)(el->el_line.lastchar - el->el_line.buffer);
  			break;

 @@ -701,6 +715,8 @@ FUN(el,gets)(EditLine *el, int *nread)
  		el->el_chared.c_vcmd.action = NOP;
  		if (el->el_flags & UNBUFFERED)
  			break;
 +		if (cmdstate != OKCMD)
 +			break;
  	}

  	terminal__flush(el);		/* flush any buffered output */

 --=_50521df0.GUGyPhvl+wFO2fsogriKx2qrb0wBUv14DwebV0W/v0GtimcZ
 Content-Type: text/plain;
  charset=us-ascii
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="libedit-test.shar"

 # This is a shell archive.  Save it in a file, remove anything before
 # this line, and then unpack it by entering "sh file".  Note, it may
 # create directories; files and directories will be owned by you and
 # have default permissions.
 #
 # Archives produced using this implementation of shar may be easily
 # examined with the command:
 #	$ grep '^[^X#]' shell-archive
 #
 # This archive contains:
 #	test.c
 #	read.c.debug
 #
 echo xx - test.c
 sed 's/^X//' << \! | uudecode | gunzip -c -f > "test.c"
 Xbegin-base64 664 /dev/stdout
 XH4sIAEQKUlAAA3VTXU/bQBB8tn/FNlWQbQwEVX3BSapSAkJyg5SQl1IUXe1LcpJzju7OiFLx37u7
 Xlw+XtpEi27Oze7Oze+F7pYuqKSX0pTGnq2F4AKxaalG9wVyp6reQUXpJWAtstELqG3CFmCyVYzgI
 XzpIhXBspL6dXkJwhYJ1wqoBiJQxshLFSy2dXPFzOrqe33x6zFqPW1nleYqp5sWnFlHYgq3kldcZn
 X9NtnhAdSICph1vOibrTL9oGnWpUhNr4qq4gq4Wsc/gqD4+M/6EFExBijWfgahsRcC6U5RZhlkW7F
 XJfjxxAXQpabgeqJwqtZgBZYhvjb4MkJbcqUlJLKCATWgtHIRpT/0HlMg3zU/6sbxE8cVU4UFRJQy
 XgPEsz2NsGQPP0XkKnW2Rzo5GwmAI50yq5lY6zExhlM9nY/T4ejQZXaUYRjeCHy/S1NGRFXiWepH1
 XIrIipkJWnFoxXwldVtKg0iNvFkV2rUXT25vP+eRrCpzPuqjmojYQZVkMaIcXdLAU+vCBdPmpRB85
 X4e8NoSweeLvhYIuQa0vpLHd15HeAJP8nSxufgizCe/AJ/xdwcp6xP1ayzjaNAlwMsSH4teRSnuQB
 XJq3lutj8jA5LnAILSHHacbvMu11t7woPhgSdDPxe7Ls73gOvQOJaId8TxV7/sfFBsNjgBXU4QV4a
 XXIwB/b7rDtXo3I+m9/Dlbnw/ucsvvMpBF4V6IYNuSZrxcQH97mlih5iX7k3f0YiTckN96MVbJwk6
 XOMBt7wT3vMd8An/gJaJvqUucHlGNdI3REPViumG/AUVu08qnBAAA
 X====
 !
 echo xx - read.c.debug
 sed 's/^X//' << \! | uudecode | gunzip -c -f > "read.c.debug"
 Xbegin-base64 664 /dev/stdout
 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
 X====
 !
 exit


 --=_50521df0.GUGyPhvl+wFO2fsogriKx2qrb0wBUv14DwebV0W/v0GtimcZ--

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.