Blob Blame History Raw
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);