diff -up mksh/exec.c.fixtrace mksh/exec.c
--- mksh/exec.c.fixtrace 2013-04-26 23:23:09.000000000 +0200
+++ mksh/exec.c 2017-10-10 12:11:30.472249513 +0200
@@ -138,11 +138,6 @@ execute(struct op * volatile t,
/* Allow option parsing (bizarre, but POSIX) */
timex_hook(t, &up);
ap = (const char **)up;
- if (Flag(FXTRACE)) {
- shf_puts(substitute(str_val(global("PS4")), 0),
- shl_out);
- Flag(FXTRACE) = 2;
- }
if (ap[0])
tp = findcom(ap[0], FC_BI|FC_FUNC);
}
@@ -637,6 +632,8 @@ comexec(struct op *t, struct tbl * volat
l_assign = e->loc;
if (Flag(FEXPORT))
type_flags |= EXPORT;
+ if (Flag(FXTRACE))
+ change_xtrace(2, false);
for (i = 0; t->vars[i]; i++) {
/* do NOT lookup in the new var/fn block just created */
e->loc = l_expand;
@@ -650,9 +647,9 @@ comexec(struct op *t, struct tbl * volat
++ccp;
if (*ccp == '=')
++ccp;
- shf_write(cp, ccp - cp, shl_out);
- print_value_quoted(shl_out, ccp);
- shf_putc(' ', shl_out);
+ shf_write(cp, ccp - cp, shl_xtrace);
+ print_value_quoted(shl_xtrace, ccp);
+ shf_putc(' ', shl_xtrace);
}
/* but assign in there as usual */
typeset(cp, type_flags, 0, 0, 0);
@@ -661,17 +658,16 @@ comexec(struct op *t, struct tbl * volat
}
if (Flag(FXTRACE)) {
+ change_xtrace(2, false);
if (ap[rv = 0]) {
xtrace_ap_loop:
- print_value_quoted(shl_out, ap[rv]);
+ print_value_quoted(shl_xtrace, ap[rv]);
if (ap[++rv]) {
- shf_putc(' ', shl_out);
+ shf_putc(' ', shl_xtrace);
goto xtrace_ap_loop;
}
}
- shf_putc('\n', shl_out);
- Flag(FXTRACE) = 1;
- shf_flush(shl_out);
+ change_xtrace(1, false);
}
if ((cp = *ap) == NULL) {
@@ -754,9 +750,9 @@ comexec(struct op *t, struct tbl * volat
getopts_reset(1);
}
- old_xflag = Flag(FXTRACE);
- Flag(FXTRACE) |= tp->flag & TRACE ? 1 : 0;
-
+ old_xflag = Flag(FXTRACE) ? 1 : 0;
+ change_xtrace((Flag(FXTRACEREC) ? old_xflag : 0) |
+ ((tp->flag & TRACE) ? 1 : 0), false);
old_inuse = tp->flag & FINUSE;
tp->flag |= FINUSE;
@@ -765,9 +761,11 @@ comexec(struct op *t, struct tbl * volat
execute(tp->val.t, flags & XERROK, NULL);
i = LRETURN;
}
+
kshname = old_kshname;
- Flag(FXTRACE) = old_xflag;
+ change_xtrace(old_xflag, false);
tp->flag = (tp->flag & ~FINUSE) | old_inuse;
+
/*
* Were we deleted while executing? If so, free the
* execution tree. TODO: Unfortunately, the table entry
@@ -1308,8 +1306,11 @@ iosetup(struct ioword *iop, struct tbl *
iotmp.name = (iotype == IOHERE) ? NULL : cp;
iotmp.flag |= IONAMEXP;
- if (Flag(FXTRACE) == 2)
- fptreef(shl_out, 0, "%R", &iotmp);
+ if (Flag(FXTRACE)) {
+ change_xtrace(2, false);
+ fptreef(shl_xtrace, 0, "%R", &iotmp);
+ change_xtrace(1, false);
+ }
switch (iotype) {
case IOREAD:
diff -up mksh/main.c.fixtrace mksh/main.c
--- mksh/main.c.fixtrace 2013-05-02 22:22:08.000000000 +0200
+++ mksh/main.c 2013-07-21 20:47:44.000000000 +0200
@@ -332,6 +343,11 @@ main_init(int argc, const char *argv[],
*/
Flag(FBRACEEXPAND) = 1;
+ /*
+ * Turn on "set -x" inheritance by default.
+ */
+ Flag(FXTRACEREC) = 1;
+
#ifndef MKSH_NO_CMDLINE_EDITING
/*
* Set edit mode to emacs by default, may be overridden
@@ -1373,7 +1393,7 @@ initio(void)
/* force buffer allocation */
shf_fdopen(1, SHF_WR, shl_stdout);
shf_fdopen(2, SHF_WR, shl_out);
- shf_fdopen(2, SHF_WR, shl_spare);
+ shf_fdopen(2, SHF_WR, shl_xtrace);
#ifdef DF
if ((lfp = getenv("SDMKSH_PATH")) == NULL) {
if ((lfp = getenv("HOME")) == NULL || *lfp != '/')
diff -up mksh/misc.c.fixtrace mksh/misc.c
--- mksh/misc.c.fixtrace 2013-05-02 22:22:09.000000000 +0200
+++ mksh/misc.c 2017-10-10 12:11:30.472249513 +0200
@@ -229,8 +229,12 @@ void
change_flag(enum sh_flag f, int what, bool newset)
{
unsigned char oldval;
- unsigned char newval;
+ unsigned char newval = (newset ? 1 : 0);
+ if (f == FXTRACE) {
+ change_xtrace(newval, true);
+ return;
+ }
oldval = Flag(f);
Flag(f) = newval = (newset ? 1 : 0);
#ifndef MKSH_UNEMPLOYED
@@ -286,6 +290,37 @@ change_flag(enum sh_flag f, int what, bo
}
}
+void
+change_xtrace(unsigned char newval, bool dosnapshot)
+{
+ if (!dosnapshot && newval == Flag(FXTRACE))
+ return;
+
+ if (Flag(FXTRACE) == 2) {
+ shf_putc('\n', shl_xtrace);
+ Flag(FXTRACE) = 1;
+ shf_flush(shl_xtrace);
+ }
+
+ if (!dosnapshot && Flag(FXTRACE) == 1)
+ switch (newval) {
+ case 1:
+ return;
+ case 2:
+ goto changed_xtrace;
+ }
+
+ shf_flush(shl_xtrace);
+ if (shl_xtrace->fd != 2)
+ close(shl_xtrace->fd);
+ if (!newval || (shl_xtrace->fd = savefd(2)) == -1)
+ shl_xtrace->fd = 2;
+
+ changed_xtrace:
+ if ((Flag(FXTRACE) = newval) == 2)
+ shf_puts(substitute(str_val(global("PS4")), 0), shl_xtrace);
+}
+
/*
* Parse command line and set command arguments. Returns the index of
* non-option arguments, -1 if there is an error.
@@ -444,8 +479,10 @@ parse_args(const char **argv,
(argv[go.optind][0] == '-' || argv[go.optind][0] == '+') &&
argv[go.optind][1] == '\0') {
/* lone - clears -v and -x flags */
- if (argv[go.optind][0] == '-')
- Flag(FVERBOSE) = Flag(FXTRACE) = 0;
+ if (argv[go.optind][0] == '-') {
+ Flag(FVERBOSE) = 0;
+ change_xtrace(0, false);
+ }
/* set skips lone - or + option */
go.optind++;
}
diff -up mksh/sh_flags.h.fixtrace mksh/sh_flags.h
--- mksh/sh_flags.h.fixtrace 2013-05-02 22:28:40.000000000 +0200
+++ mksh/sh_flags.h 2017-10-10 12:11:30.472249513 +0200
@@ -45,6 +45,9 @@ FN("gmacs", FGMACS, 0, OF_ANY)
/* ./. reading EOF does not exit */
FN("ignoreeof", FIGNOREEOF, 0, OF_ANY)
+/* ./. inherit -x flag */
+FN("inherit-xtrace", FXTRACEREC, 0, OF_ANY)
+
/* -i interactive shell */
FN("interactive", FTALKING, 'i', OF_CMDLINE)
diff -up mksh/sh.h.fixtrace mksh/sh.h
--- mksh/sh.h.fixtrace 2013-05-03 00:00:17.000000000 +0200
+++ mksh/sh.h 2017-10-10 12:11:30.472249513 +0200
@@ -837,7 +837,7 @@ struct temp {
* stdio and our IO routines
*/
-#define shl_spare (&shf_iob[0]) /* for c_read()/c_print() */
+#define shl_xtrace (&shf_iob[0]) /* for set -x */
#define shl_stdout (&shf_iob[1])
#define shl_out (&shf_iob[2])
#ifdef DF
@@ -1905,6 +1905,7 @@ void initctypes(void);
size_t option(const char *);
char *getoptions(void);
void change_flag(enum sh_flag, int, bool);
+void change_xtrace(unsigned char, bool);
int parse_args(const char **, int, bool *);
int getn(const char *, int *);
int gmatchx(const char *, const char *, bool);