diff --git a/SOURCES/mksh-46-fixtrace.patch b/SOURCES/mksh-46-fixtrace.patch new file mode 100644 index 0000000..5273144 --- /dev/null +++ b/SOURCES/mksh-46-fixtrace.patch @@ -0,0 +1,224 @@ +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); diff --git a/SOURCES/mksh-46-selectopts.patch b/SOURCES/mksh-46-selectopts.patch new file mode 100644 index 0000000..be4ff90 --- /dev/null +++ b/SOURCES/mksh-46-selectopts.patch @@ -0,0 +1,18 @@ +diff -up mksh/exec.c.selectopts mksh/exec.c +--- mksh/exec.c.selectopts 2017-09-14 14:15:27.335249169 +0200 ++++ mksh/exec.c 2017-09-14 14:16:30.120467641 +0200 +@@ -1560,11 +1560,9 @@ do_selectargs(const char **ap, bool prin + shellf("%s", str_val(global("PS3"))); + if (call_builtin(findcom("read", FC_BI), read_args, Tselect)) + return (NULL); +- s = str_val(global("REPLY")); +- if (*s) { +- getn(s, &i); +- return ((i >= 1 && i <= argct) ? ap[i - 1] : null); +- } ++ if (*(s = str_val(global("REPLY")))) ++ return ((getn(s, &i) && i >= 1 && i <= argct) ? ++ ap[i - 1] : null); + print_menu = true; + } + } diff --git a/SOURCES/mksh-55-waitfail.patch b/SOURCES/mksh-55-waitfail.patch new file mode 100644 index 0000000..a40ff45 --- /dev/null +++ b/SOURCES/mksh-55-waitfail.patch @@ -0,0 +1,20 @@ +diff -up mksh/jobs.c.waitfail mksh/jobs.c +--- mksh/jobs.c.waitfail 2017-08-09 10:06:36.500591694 +0200 ++++ mksh/jobs.c 2017-08-09 10:08:34.325534710 +0200 +@@ -1009,8 +1009,14 @@ j_notify(void) + } + for (j = job_list; j; j = tmp) { + tmp = j->next; +- if (j->flags & JF_REMOVE) +- remove_job(j, "notify"); ++ if (j->flags & JF_REMOVE) { ++ if (j == async_job || (j->flags & JF_KNOWN)) { ++ j->flags = (j->flags & ~JF_REMOVE) | JF_ZOMBIE; ++ j->job = -1; ++ nzombie++; ++ } else ++ remove_job(j, "notify"); ++ } + } + shf_flush(shl_out); + #ifndef MKSH_NOPROSPECTOFWORK diff --git a/SPECS/mksh.spec b/SPECS/mksh.spec index 92e1213..b4f9a9a 100644 --- a/SPECS/mksh.spec +++ b/SPECS/mksh.spec @@ -2,7 +2,7 @@ Summary: MirBSD enhanced version of the Korn Shell Name: mksh Version: 46 -Release: 5%{?dist} +Release: 8%{?dist} # BSD (setmode.c), ISC (strlcpy.c), MirOS (the rest) License: MirOS and ISC and BSD Group: System Environment/Shells @@ -11,6 +11,12 @@ Source0: http://www.mirbsd.org/MirOS/dist/mir/%{name}/%{name}-R%{versio Source1: dot-mkshrc Source2: rtchecks.expected Patch0: mksh-46-lksh.patch +# from upstream, for mksh <= 55, rhbz#1243788 +Patch1: mksh-55-waitfail.patch +# from upstream, for mksh <= 50f, rhbz#1491312 +Patch2: mksh-46-selectopts.patch +# from upstream, for mksh < 47, rhbz#1413023 +Patch3: mksh-46-fixtrace.patch Requires: chkconfig Requires(post): grep, chkconfig Requires(postun): sed @@ -29,6 +35,9 @@ bourne shell replacement, pdksh successor and an alternative to the C shell. %prep %setup -q -n %{name} %patch0 -p0 -b .lksh +%patch1 -p1 -b .waitfail +%patch2 -p1 -b .selectopts +%patch3 -p1 -b .fixtrace # we'll need this later cat >rtchecks <<'EOF' @@ -145,6 +154,15 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man1/lksh.1* %changelog +* Tue Oct 10 2017 Michal Hlavinka - 46-8 +- fix infinite recursion in PS4 (#1413023) + +* Thu Sep 14 2017 Michal Hlavinka - 46-7 +- fix select setting wrong value on incorrect input (#1491312) + +* Wed Aug 09 2017 Michal Hlavinka - 46-6 +- do not forget exit codes of co-processes in interactive mode (#1243788) + * Fri Jan 24 2014 Daniel Mach - 46-5 - Mass rebuild 2014-01-24