oksh-noxz

[fork] Portable OpenBSD ksh, based on the Public Domain Korn Shell (pdksh).
git clone https://noxz.tech/git/oksh-noxz.git
oksh-noxz

commit: 203506e928606056da4bee720fa0b1c921957f20
parent: 53b138c80a1f6d35e7eb834ff4343a512058f513
author: Brian Callahan <bcallah@openbsd.org>
date:   Sun, 12 Jul 2020 10:39:24 -0400
Update to latest OpenBSD code.

Brings in these two commits:
---
date: 2020/05/22 07:50:07;  author: benno;  state: Exp;  lines: +7 -1;  commitid: H8MJhjoH6o7bDIkz;
Fix the exit code when eval()uating a || compound list, it would
terminate the shell when running under -e.
See also https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=269067 and
Bug reported including fix by Leah Neukirchen, Thanks!
ok millert@
---

---
date: 2020/07/07 10:33:58;  author: jca;  state: Exp;  lines: +28 -2;  commitid: Yo5zapKJfyJKPH39;
Add support for set -o pipefail

With the pipefail option set, the exit status of a pipeline is 0 if all
commands succeed, or the return status of the rightmost command that
fails.  This can help stronger error checking, but is not a silver
bullet.  For example, commands will exhibit a non-zero exit status if
they're killed by a SIGPIPE when writing to a pipe.  Yet pipefail was
considered useful enough to be included in the next POSIX standard.

This implementation remembers the value of the pipefail option when
a pipeline is started, as described as option 1) in

  https://www.austingroupbugs.net/view.php?id=789#c4102

Requested by ajacoutot@, ok millert@
---
MCVS/Entries66++++++++++----------
DCVS/Entries.Log2-
Mc_sh.c8++-
Mjobs.c30++++++++-
Mksh.112+++-
Mmisc.c3+-
Msh.h3+-
7 files changed, 81 insertions(+), 43 deletions(-)
diff --git a/CVS/Entries b/CVS/Entries
@@ -1,46 +1,46 @@
 /config.h/1.19/Tue Jan 16 02:21:56 2018//
-/sh.h/1.75/Result of merge//
 /c_test.c/1.27/Result of merge//
 /edit.c/1.69/Result of merge//
 /eval.c/1.65/Result of merge//
 /exec.c/1.74/Result of merge//
 /main.c/1.98/Result of merge//
-/misc.c/1.73/Result of merge//
 /tty.c/1.18/Result of merge+Tue Jul 23 23:36:05 2019//
 /io.c/1.38/Result of merge//
 /history.c/1.84/Result of merge//
 /trap.c/1.33/Tue Dec 17 00:39:35 2019//
 /var.c/1.71/Result of merge//
-/CONTRIBUTORS/1.11/Fri May  8 05:24:01 2020//
-/LEGAL/1.2/Fri May  8 05:24:01 2020//
-/Makefile/1.39/Fri May  8 17:43:41 2020//
-/NOTES/1.16/Fri May  8 05:24:01 2020//
-/PROJECTS/1.9/Fri May  8 05:24:01 2020//
-/README/1.16/Fri May  8 17:43:41 2020//
-/alloc.c/1.19/Fri May  8 05:24:01 2020//
-/c_ksh.c/1.62/Fri May  8 05:24:01 2020//
-/c_sh.c/1.63/Fri May  8 05:24:01 2020//
-/c_test.h/1.4/Fri May  8 05:24:01 2020//
-/c_ulimit.c/1.29/Fri May  8 05:24:01 2020//
-/edit.h/1.12/Fri May  8 05:24:01 2020//
 /emacs.c/1.87/Result of merge//
-/expand.h/1.15/Fri May  8 05:24:01 2020//
-/expr.c/1.34/Fri May  8 05:24:01 2020//
-/jobs.c/1.61/Fri May  8 05:24:01 2020//
-/ksh.1/1.208/Fri May  8 05:24:01 2020//
-/lex.c/1.78/Fri May  8 05:24:01 2020//
-/lex.h/1.21/Fri May  8 05:24:01 2020//
-/mail.c/1.27/Fri May  8 05:24:01 2020//
-/path.c/1.23/Fri May  8 05:24:01 2020//
-/sh.1/1.152/Fri May  8 05:24:01 2020//
-/shf.c/1.34/Fri May  8 05:24:01 2020//
-/shf.h/1.8/Fri May  8 05:24:01 2020//
-/syn.c/1.39/Fri May  8 05:24:01 2020//
-/table.c/1.25/Fri May  8 05:24:01 2020//
-/table.h/1.15/Fri May  8 05:24:01 2020//
-/tree.c/1.34/Fri May  8 05:24:01 2020//
-/tree.h/1.12/Fri May  8 05:24:01 2020//
-/tty.h/1.6/Fri May  8 05:24:01 2020//
-/version.c/1.12/Fri May  8 05:24:01 2020//
-/vi.c/1.56/Fri May  8 05:24:01 2020//
+/CONTRIBUTORS/1.11/Sun Jul 12 14:32:42 2020//
+/LEGAL/1.2/Sun Jul 12 14:32:42 2020//
+/Makefile/1.39/Sun Jul 12 14:32:50 2020//
+/NOTES/1.16/Sun Jul 12 14:32:42 2020//
+/PROJECTS/1.9/Sun Jul 12 14:32:42 2020//
+/README/1.16/Sun Jul 12 14:32:50 2020//
+/alloc.c/1.19/Sun Jul 12 14:32:42 2020//
+/c_ksh.c/1.62/Sun Jul 12 14:32:42 2020//
+/c_sh.c/1.64/Sun Jul 12 14:32:50 2020//
+/c_test.h/1.4/Sun Jul 12 14:32:42 2020//
+/c_ulimit.c/1.29/Sun Jul 12 14:32:42 2020//
+/edit.h/1.12/Sun Jul 12 14:32:42 2020//
+/expand.h/1.15/Sun Jul 12 14:32:42 2020//
+/expr.c/1.34/Sun Jul 12 14:32:42 2020//
+/jobs.c/1.62/Sun Jul 12 14:32:50 2020//
+/ksh.1/1.209/Sun Jul 12 14:32:50 2020//
+/lex.c/1.78/Sun Jul 12 14:32:42 2020//
+/lex.h/1.21/Sun Jul 12 14:32:42 2020//
+/mail.c/1.27/Sun Jul 12 14:32:42 2020//
+/misc.c/1.74/Result of merge//
+/path.c/1.23/Sun Jul 12 14:32:42 2020//
+/sh.1/1.152/Sun Jul 12 14:32:42 2020//
+/sh.h/1.76/Result of merge//
+/shf.c/1.34/Sun Jul 12 14:32:42 2020//
+/shf.h/1.8/Sun Jul 12 14:32:42 2020//
+/syn.c/1.39/Sun Jul 12 14:32:42 2020//
+/table.c/1.25/Sun Jul 12 14:32:42 2020//
+/table.h/1.15/Sun Jul 12 14:32:42 2020//
+/tree.c/1.34/Sun Jul 12 14:32:42 2020//
+/tree.h/1.12/Sun Jul 12 14:32:42 2020//
+/tty.h/1.6/Sun Jul 12 14:32:42 2020//
+/version.c/1.12/Sun Jul 12 14:32:42 2020//
+/vi.c/1.56/Sun Jul 12 14:32:42 2020//
 D
diff --git a/CVS/Entries.Log b/CVS/Entries.Log
@@ -1,2 +0,0 @@
-A D/tests////
-R D/tests////
diff --git a/c_sh.c b/c_sh.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: c_sh.c,v 1.63 2018/04/09 17:53:36 tobias Exp $	*/
+/*	$OpenBSD: c_sh.c,v 1.64 2020/05/22 07:50:07 benno Exp $	*/
 
 /*
  * built-in Bourne commands
@@ -424,6 +424,8 @@ int
 c_eval(char **wp)
 {
 	struct source *s;
+	struct source *saves = source;
+	int savef;
 	int rv;
 
 	if (ksh_getopt(wp, &builtin_opt, null) == '?')
@@ -458,7 +460,11 @@ c_eval(char **wp)
 		exstat = subst_exstat;
 	}
 
+	savef = Flag(FERREXIT);
+	Flag(FERREXIT) = 0;
 	rv = shell(s, false);
+	Flag(FERREXIT) = savef;
+	source = saves;
 	afree(s, ATEMP);
 	return (rv);
 }
diff --git a/jobs.c b/jobs.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: jobs.c,v 1.61 2019/06/28 13:34:59 deraadt Exp $	*/
+/*	$OpenBSD: jobs.c,v 1.62 2020/07/07 10:33:58 jca Exp $	*/
 
 /*
  * Process and job control
@@ -70,6 +70,7 @@ struct proc {
 #define JF_REMOVE	0x200	/* flagged for removal (j_jobs()/j_notify()) */
 #define JF_USETTYMODE	0x400	/* tty mode saved if process exits normally */
 #define JF_SAVEDTTYPGRP	0x800	/* j->saved_ttypgrp is valid */
+#define JF_PIPEFAIL	0x1000	/* pipefail on when job was started */
 
 typedef struct job Job;
 struct job {
@@ -421,6 +422,8 @@ exchild(struct op *t, int flags, volatile int *xerrok,
 		 */
 		j->flags = (flags & XXCOM) ? JF_XXCOM :
 		    ((flags & XBGND) ? 0 : (JF_FG|JF_USETTYMODE));
+		if (Flag(FPIPEFAIL))
+			j->flags |= JF_PIPEFAIL;
 		timerclear(&j->usrtime);
 		timerclear(&j->systime);
 		j->state = PRUNNING;
@@ -1084,7 +1087,30 @@ j_waitj(Job *j,
 
 	j_usrtime = j->usrtime;
 	j_systime = j->systime;
-	rv = j->status;
+
+	if (j->flags & JF_PIPEFAIL) {
+		Proc *p;
+		int status;
+
+		rv = 0;
+		for (p = j->proc_list; p != NULL; p = p->next) {
+			switch (p->state) {
+			case PEXITED:
+				status = WEXITSTATUS(p->status);
+				break;
+			case PSIGNALLED:
+				status = 128 + WTERMSIG(p->status);
+				break;
+			default:
+				status = 0;
+				break;
+			}
+			if (status)
+				rv = status;
+		}
+	} else
+		rv = j->status;
+
 
 	if (!(flags & JW_ASYNCNOTIFY) &&
 	    (!Flag(FMONITOR) || j->state != PSTOPPED)) {
diff --git a/ksh.1 b/ksh.1
@@ -1,8 +1,8 @@
-.\"	$OpenBSD: ksh.1,v 1.208 2019/11/26 22:49:01 jmc Exp $
+.\"	$OpenBSD: ksh.1,v 1.209 2020/07/07 10:33:58 jca Exp $
 .\"
 .\"	Public Domain
 .\"
-.Dd $Mdocdate: November 26 2019 $
+.Dd $Mdocdate: July 7 2020 $
 .Dt KSH 1
 .Os
 .Sh NAME
@@ -361,7 +361,9 @@ token to form pipelines, in which the standard output of each command but the
 last is piped (see
 .Xr pipe 2 )
 to the standard input of the following command.
-The exit status of a pipeline is that of its last command.
+The exit status of a pipeline is that of its last command, unless the
+.Ic pipefail
+option is set.
 A pipeline may be prefixed by the
 .Ql \&!
 reserved word, which causes the exit status of the pipeline to be logically
@@ -3664,6 +3666,10 @@ See the
 and
 .Ic pwd
 commands above for more details.
+.It Ic pipefail
+The exit status of a pipeline is the exit status of the rightmost
+command in the pipeline that doesn't return 0, or 0 if all commands
+returned a 0 exit status.
 .It Ic posix
 Enable POSIX mode.
 See
diff --git a/misc.c b/misc.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: misc.c,v 1.73 2019/06/28 13:34:59 deraadt Exp $	*/
+/*	$OpenBSD: misc.c,v 1.74 2020/07/07 10:33:58 jca Exp $	*/
 
 /*
  * Miscellaneous functions
@@ -147,6 +147,7 @@ const struct option sh_options[] = {
 	{ "notify",	'b',		OF_ANY },
 	{ "nounset",	'u',		OF_ANY },
 	{ "physical",	  0,		OF_ANY }, /* non-standard */
+	{ "pipefail",	  0,		OF_ANY }, /* non-standard */
 	{ "posix",	  0,		OF_ANY }, /* non-standard */
 	{ "privileged",	'p',		OF_ANY },
 	{ "restricted",	'r',	    OF_CMDLINE },
diff --git a/sh.h b/sh.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: sh.h,v 1.75 2019/02/20 23:59:17 schwarze Exp $	*/
+/*	$OpenBSD: sh.h,v 1.76 2020/07/07 10:33:58 jca Exp $	*/
 
 /*
  * Public Domain Bourne/Korn shell
@@ -158,6 +158,7 @@ enum sh_flag {
 	FNOTIFY,	/* -b: asynchronous job completion notification */
 	FNOUNSET,	/* -u: using an unset var is an error */
 	FPHYSICAL,	/* -o physical: don't do logical cd's/pwd's */
+	FPIPEFAIL,	/* -o pipefail: all commands in pipeline can affect $? */
 	FPOSIX,		/* -o posix: be posixly correct */
 	FPRIVILEGED,	/* -p: use suid_profile */
 	FRESTRICTED,	/* -r: restricted shell */