@@ -, +, @@ Fix PR bin/170651 --- b/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; } --- b/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); --- b/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') { --- b/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 *); - --- b/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); } --- b/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 --- b/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