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>
