Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 1 Sep 2012 15:40:13 GMT
From:      Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/170651: On 9.0-RELEASE#0 and master sh(1) gobbles high bit at first
Message-ID:  <201209011540.q81FeDQi027140@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/170651; it has been noted by GNATS.

From: Steffen "Daode" Nurpmeso <sdaoden@gmail.com>
To: bug-followup@FreeBSD.org
Cc: jilles@stack.nl, eadler@FreeBSD.org
Subject: Re: bin/170651: On 9.0-RELEASE#0 and master sh(1) gobbles high bit at first
Date: Sat, 01 Sep 2012 17:33:04 +0200

 Steffen "Daode" Nurpmeso <sdaoden@gmail.com> wrote:
  |Steffen "Daode" Nurpmeso <sdaoden@gmail.com> wrote:
  ||Jilles Tjoelker <jilles@stack.nl> wrote:
  |||This PR bin/170651 does in fact look valid. It looks like libedit only
  [.]
  |||-- 
  |||Jilles Tjoelker
  [.]
  |So i think this should encapsulate itself further than what
  |currently happens and what i've sent to you already, and instead
  |act upon real changes on the actual iflag/Vflag/Eflag combination
  |only.
  [.]
 
 This is what i come up with, and it works smoothly.
 
 One exception is maybe the histedit_init=2 case with the bundled
 delayed histedit(1) from within main().  If that would be possible
 it'll most likely safe a lot of (up to three in my case since my
 shell init scripts only set LC_ALL and LANG) calls to histedit()
 which actually would *force* a reinitialization, but i'm not
 really convinced it'll work at this very place and in respect to
 what bind(1) and such return from if used from within the init
 scripts...
 So, i hate to say it, the following additional patch is maybe
 necessary for real in addition.  (Sob.)
 
   |diff --git a/bin/sh/histedit.c b/bin/sh/histedit.c
   |index bd47c0d..0f6d2ba 100644
   |--- a/bin/sh/histedit.c
   |+++ b/bin/sh/histedit.c
   |@@ -90,7 +90,6 @@ histedit(int force)
   | 	if (! histedit_init)
   | 		return;
   | 
   |-	histedit_init = 2;
   | 	/* options.c ensures these are mutual exclusive */
   | 	nedstate = (Eflag ? 1 : 0) | (Vflag ? 2 : 0);
   | 
   |diff --git a/bin/sh/main.c b/bin/sh/main.c
   |index 684ce8c..ec2275b 100644
   |--- a/bin/sh/main.c
   |+++ b/bin/sh/main.c
   |@@ -151,6 +151,7 @@ main(int argc, char *argv[])
   | 		chkmail(1);
   | #ifndef NO_HISTORY
   | 		histedit_init = 1;
   |+		histedit(1);
   | #endif
   | 	}
   | 	if (argv[0] && argv[0][0] == '-') {
   |@@ -164,10 +165,6 @@ state1:
   | 			read_profile("/etc/suid_profile");
   | 	}
   | state2:
   |-#ifndef NO_HISTORY
   |-	if (iflag && histedit_init != 2)
   |-		histedit(1);
   |-#endif
   | 	state = 3;
   | 	if (!privileged && iflag) {
   | 		if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
 
 Thanks for FreeBSD, eh?
 
 --steffen
 
 diff --git a/bin/sh/histedit.c b/bin/sh/histedit.c
 index 6371599..bd47c0d 100644
 --- a/bin/sh/histedit.c
 +++ b/bin/sh/histedit.c
 @@ -67,7 +67,9 @@ __FBSDID("$FreeBSD$");
  History *hist;	/* history cookie */
  EditLine *el;	/* editline cookie */
  int displayhist;
 +int histedit_init;
  static FILE *el_in, *el_out, *el_err;
 +static int e1v2;
  
  static char *fc_replace(const char *, char *, char *);
  static int not_fcnumber(const char *);
 @@ -76,12 +78,21 @@ static int str_to_event(const char *, int);
  /*
   * Set history and editing status.  Called whenever the status may
   * have changed (figures out what to do).
 + * If force is set then an editline reinit is issued even if the actual edit
 + * mode hasn't changed - necessary after the locale has changed because
 + * editline bases it's decision what is reported or not upon isprint(3)
   */
  void
 -histedit(void)
 +histedit(int force)
  {
 +	int nedstate;
  
 -#define editing (Eflag || Vflag)
 +	if (! histedit_init)
 +		return;
 +
 +	histedit_init = 2;
 +	/* options.c ensures these are mutual exclusive */
 +	nedstate = (Eflag ? 1 : 0) | (Vflag ? 2 : 0);
  
  	if (iflag) {
  		if (!hist) {
 @@ -97,7 +108,7 @@ histedit(void)
  			else
  				out2fmt_flush("sh: can't initialize history\n");
  		}
 -		if (editing && !el && isatty(0)) { /* && isatty(2) ??? */
 +		if (nedstate && ! el && isatty(0)) { /* && isatty(2) ??? */
  			/*
  			 * turn editing on
  			 */
 @@ -130,17 +141,14 @@ bad:
  				out2fmt_flush("sh: can't initialize editing\n");
  			}
  			INTON;
 -		} else if (!editing && el) {
 +		} else if (! nedstate && el) {
  			INTOFF;
  			el_end(el);
  			el = NULL;
  			INTON;
  		}
 -		if (el) {
 -			if (Vflag)
 -				el_set(el, EL_EDITOR, "vi");
 -			else if (Eflag)
 -				el_set(el, EL_EDITOR, "emacs");
 +		if (el && (nedstate != e1v2 || force)) {
 +			el_set(el, EL_EDITOR, (nedstate & 1) ? "emacs" : "vi");
  			el_set(el, EL_BIND, "^I", "sh-complete", NULL);
  			el_source(el, NULL);
  		}
 @@ -155,7 +163,10 @@ bad:
  			hist = NULL;
  		}
  		INTON;
 +		nedstate = 0;
  	}
 +
 +	e1v2 = nedstate;
  }
  
  
 diff --git a/bin/sh/input.c b/bin/sh/input.c
 index 12f285f..1da03c6 100644
 --- a/bin/sh/input.c
 +++ b/bin/sh/input.c
 @@ -59,8 +59,10 @@ __FBSDID("$FreeBSD$");
  #include "error.h"
  #include "alias.h"
  #include "parser.h"
 -#include "myhistedit.h"
  #include "trap.h"
 +#ifndef NO_HISTORY
 +# include "myhistedit.h"
 +#endif
  
  #define EOF_NLEFT -99		/* value of parsenleft when EOF pushed back */
  
 @@ -102,8 +104,6 @@ static struct parsefile *parsefile = &basepf;	/* current input file */
  int init_editline = 0;		/* editline library initialized? */
  int whichprompt;		/* 1 == PS1, 2 == PS2 */
  
 -EditLine *el;			/* cookie for editline package */
 -
  static void pushfile(void);
  static int preadfd(void);
  static void popstring(void);
 diff --git a/bin/sh/main.c b/bin/sh/main.c
 index 5eb12e0..684ce8c 100644
 --- a/bin/sh/main.c
 +++ b/bin/sh/main.c
 @@ -73,6 +73,9 @@ __FBSDID("$FreeBSD$");
  #include "exec.h"
  #include "cd.h"
  #include "builtins.h"
 +#ifndef NO_HISTORY
 +# include "myhistedit.h"
 +#endif
  
  int rootpid;
  int rootshell;
 @@ -144,8 +147,12 @@ main(int argc, char *argv[])
  	setstackmark(&smark2);
  	procargs(argc, argv);
  	pwd_init(iflag);
 -	if (iflag)
 +	if (iflag) {
  		chkmail(1);
 +#ifndef NO_HISTORY
 +		histedit_init = 1;
 +#endif
 +	}
  	if (argv[0] && argv[0][0] == '-') {
  		state = 1;
  		read_profile("/etc/profile");
 @@ -157,6 +164,10 @@ state1:
  			read_profile("/etc/suid_profile");
  	}
  state2:
 +#ifndef NO_HISTORY
 +	if (iflag && histedit_init != 2)
 +		histedit(1);
 +#endif
  	state = 3;
  	if (!privileged && iflag) {
  		if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
 diff --git a/bin/sh/myhistedit.h b/bin/sh/myhistedit.h
 index e31276d..24123e1 100644
 --- a/bin/sh/myhistedit.h
 +++ b/bin/sh/myhistedit.h
 @@ -35,8 +35,8 @@
  extern History *hist;
  extern EditLine *el;
  extern int displayhist;
 +extern int histedit_init;
  
 -void histedit(void);
 +void histedit(int);
  void sethistsize(const char *);
  void setterm(const char *);
 -
 diff --git a/bin/sh/options.c b/bin/sh/options.c
 index 4c2c8ab..5198a52 100644
 --- a/bin/sh/options.c
 +++ b/bin/sh/options.c
 @@ -58,7 +58,7 @@ __FBSDID("$FreeBSD$");
  #include "mystring.h"
  #include "builtins.h"
  #ifndef NO_HISTORY
 -#include "myhistedit.h"
 +# include "myhistedit.h"
  #endif
  
  char *arg0;			/* value of $0 */
 @@ -131,7 +131,7 @@ optschanged(void)
  {
  	setinteractive(iflag);
  #ifndef NO_HISTORY
 -	histedit();
 +	histedit(0);
  #endif
  	setjobctl(mflag);
  }
 diff --git a/bin/sh/trap.c b/bin/sh/trap.c
 index 521c511..b0d8b11 100644
 --- a/bin/sh/trap.c
 +++ b/bin/sh/trap.c
 @@ -56,8 +56,9 @@ __FBSDID("$FreeBSD$");
  #include "trap.h"
  #include "mystring.h"
  #include "builtins.h"
 -#include "myhistedit.h"
 -
 +#ifndef NO_HISTORY
 +# include "myhistedit.h"
 +#endif
  
  /*
   * Sigmode records the current value of the signal handlers for the various
 diff --git a/bin/sh/var.c b/bin/sh/var.c
 index 6041459..d1af678 100644
 --- a/bin/sh/var.c
 +++ b/bin/sh/var.c
 @@ -65,7 +65,7 @@ __FBSDID("$FreeBSD$");
  #include "parser.h"
  #include "builtins.h"
  #ifndef NO_HISTORY
 -#include "myhistedit.h"
 +# include "myhistedit.h"
  #endif
  
  
 @@ -523,6 +523,9 @@ updatecharset(void)
  
  	charset = nl_langinfo(CODESET);
  	localeisutf8 = !strcmp(charset, "UTF-8");
 +#ifndef NO_HISTORY
 +	histedit(1);
 +#endif
  }
  
  void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201209011540.q81FeDQi027140>