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: 34dc34c156d68e59255fa37b8d2b29f6091a474d
parent: 94493b305c8c1b5736174082c4b1ca72978e349b
author: Brian Callahan <bcallah@openbsd.org>
date:   Tue, 16 Jan 2018 23:01:05 -0500
Update to latest upstream code.
MCVS/Entries86++++++++++----------
Malloc.c12+--
Mc_ksh.c4+-
Mc_ulimit.c20+----
Medit.c8+-
Memacs.c4+-
Meval.c8+-
Mexec.c10+--
Mio.c38++++++---
Mjobs.c18++--
Mmain.c6+-
Mmisc.c4+-
Msh.h8+-
Mshf.c36++++----
Mtable.c4+-
Mtrap.c4+-
Mtree.c4+-
Mvar.c4+-
Mvi.c4+-
19 files changed, 143 insertions(+), 139 deletions(-)
diff --git a/CVS/Entries b/CVS/Entries
@@ -1,46 +1,46 @@
-/CONTRIBUTORS/1.10/Tue Jan 16 02:19:52 2018//
-/LEGAL/1.2/Tue Jan 16 02:19:52 2018//
-/NOTES/1.16/Tue Jan 16 02:19:52 2018//
-/PROJECTS/1.9/Tue Jan 16 02:19:52 2018//
-/alloc.c/1.18/Tue Jan 16 02:19:52 2018//
-/c_ksh.c/1.57/Tue Jan 16 02:20:22 2018//
-/c_sh.c/1.62/Tue Jan 16 02:19:52 2018//
-/c_test.c/1.24/Tue Jan 16 02:19:52 2018//
-/c_test.h/1.4/Tue Jan 16 02:19:52 2018//
-/c_ulimit.c/1.24/Tue Jan 16 02:19:52 2018//
-/edit.c/1.62/Tue Jan 16 02:20:22 2018//
-/edit.h/1.11/Tue Jan 16 02:19:52 2018//
-/emacs.c/1.83/Result of merge//
-/eval.c/1.58/Tue Jan 16 02:20:22 2018//
-/exec.c/1.71/Tue Jan 16 02:20:22 2018//
-/expand.h/1.15/Tue Jan 16 02:19:52 2018//
-/expr.c/1.32/Tue Jan 16 02:19:52 2018//
-/io.c/1.35/Tue Jan 16 02:19:52 2018//
-/jobs.c/1.58/Tue Jan 16 02:19:52 2018//
-/ksh.1/1.197/Tue Jan 16 02:19:52 2018//
-/lex.c/1.78/Tue Jan 16 02:20:22 2018//
-/lex.h/1.21/Tue Jan 16 02:20:22 2018//
-/mail.c/1.22/Tue Jan 16 02:19:52 2018//
-/main.c/1.88/Result of merge//
-/misc.c/1.67/Tue Jan 16 02:20:22 2018//
-/path.c/1.22/Tue Jan 16 02:19:52 2018//
-/sh.1/1.146/Tue Jan 16 02:19:52 2018//
-/sh.h/1.70/Tue Jan 16 02:20:22 2018//
-/shf.c/1.31/Tue Jan 16 02:19:52 2018//
-/shf.h/1.8/Tue Jan 16 02:19:52 2018//
-/syn.c/1.38/Tue Jan 16 02:19:52 2018//
-/table.c/1.24/Tue Jan 16 02:19:52 2018//
-/table.h/1.13/Tue Jan 16 02:19:52 2018//
-/trap.c/1.30/Tue Jan 16 02:19:52 2018//
-/tree.c/1.30/Tue Jan 16 02:19:52 2018//
-/tree.h/1.12/Tue Jan 16 02:19:52 2018//
-/tty.c/1.16/Tue Jan 16 02:19:52 2018//
-/tty.h/1.6/Tue Jan 16 02:19:52 2018//
-/var.c/1.64/Tue Jan 16 02:20:22 2018//
-/version.c/1.12/Tue Jan 16 02:19:52 2018//
-/vi.c/1.54/Tue Jan 16 02:19:52 2018//
-/Makefile/1.38/Tue Jan 16 02:21:56 2018//
-/README/1.16/Tue Jan 16 02:21:56 2018//
 /config.h/1.19/Tue Jan 16 02:21:56 2018//
 /history.c/1.80/Tue Jan 16 02:21:56 2018//
+/CONTRIBUTORS/1.10/Wed Jan 17 03:52:32 2018//
+/LEGAL/1.2/Wed Jan 17 03:52:32 2018//
+/Makefile/1.38/Wed Jan 17 03:56:16 2018//
+/NOTES/1.16/Wed Jan 17 03:52:32 2018//
+/PROJECTS/1.9/Wed Jan 17 03:52:32 2018//
+/README/1.16/Wed Jan 17 03:56:16 2018//
+/alloc.c/1.19/Wed Jan 17 03:56:16 2018//
+/c_ksh.c/1.58/Wed Jan 17 03:56:16 2018//
+/c_sh.c/1.62/Wed Jan 17 03:52:32 2018//
+/c_test.c/1.24/Wed Jan 17 03:52:32 2018//
+/c_test.h/1.4/Wed Jan 17 03:52:32 2018//
+/c_ulimit.c/1.26/Wed Jan 17 03:56:16 2018//
+/edit.c/1.63/Wed Jan 17 03:56:16 2018//
+/edit.h/1.11/Wed Jan 17 03:52:32 2018//
+/emacs.c/1.84/Result of merge//
+/eval.c/1.59/Wed Jan 17 03:56:16 2018//
+/exec.c/1.72/Wed Jan 17 03:56:16 2018//
+/expand.h/1.15/Wed Jan 17 03:52:32 2018//
+/expr.c/1.32/Wed Jan 17 03:52:32 2018//
+/io.c/1.36/Wed Jan 17 03:56:16 2018//
+/jobs.c/1.59/Wed Jan 17 03:56:16 2018//
+/ksh.1/1.197/Wed Jan 17 03:52:32 2018//
+/lex.c/1.78/Wed Jan 17 03:52:32 2018//
+/lex.h/1.21/Wed Jan 17 03:52:32 2018//
+/mail.c/1.22/Wed Jan 17 03:52:32 2018//
+/main.c/1.89/Result of merge//
+/misc.c/1.68/Wed Jan 17 03:56:16 2018//
+/path.c/1.22/Wed Jan 17 03:52:32 2018//
+/sh.1/1.146/Wed Jan 17 03:52:32 2018//
+/sh.h/1.71/Wed Jan 17 03:56:16 2018//
+/shf.c/1.32/Wed Jan 17 03:56:16 2018//
+/shf.h/1.8/Wed Jan 17 03:52:32 2018//
+/syn.c/1.38/Wed Jan 17 03:52:32 2018//
+/table.c/1.25/Wed Jan 17 03:56:16 2018//
+/table.h/1.13/Wed Jan 17 03:52:32 2018//
+/trap.c/1.31/Wed Jan 17 03:56:16 2018//
+/tree.c/1.31/Wed Jan 17 03:56:16 2018//
+/tree.h/1.12/Wed Jan 17 03:52:32 2018//
+/tty.c/1.16/Wed Jan 17 03:52:32 2018//
+/tty.h/1.6/Wed Jan 17 03:52:32 2018//
+/var.c/1.65/Wed Jan 17 03:56:16 2018//
+/version.c/1.12/Wed Jan 17 03:52:32 2018//
+/vi.c/1.55/Wed Jan 17 03:56:16 2018//
 D
diff --git a/alloc.c b/alloc.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: alloc.c,v 1.18 2017/11/02 06:55:35 tb Exp $	*/
+/*	$OpenBSD: alloc.c,v 1.19 2018/01/16 22:52:32 jca Exp $	*/
 
 /* Public domain, like most of the rest of ksh */
 
@@ -45,11 +45,11 @@ alloc(size_t size, Area *ap)
 
 	/* ensure that we don't overflow by allocating space for link */
 	if (size > SIZE_MAX - sizeof(struct link))
-		internal_errorf(1, "unable to allocate memory");
+		internal_errorf("unable to allocate memory");
 
 	l = malloc(sizeof(struct link) + size);
 	if (l == NULL)
-		internal_errorf(1, "unable to allocate memory");
+		internal_errorf("unable to allocate memory");
 	l->next = ap->freelist;
 	l->prev = NULL;
 	if (ap->freelist)
@@ -73,7 +73,7 @@ areallocarray(void *ptr, size_t nmemb, size_t size, Area *ap)
 	/* condition logic cloned from calloc() */
 	if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
 	    nmemb > 0 && SIZE_MAX / nmemb < size) {
-		internal_errorf(1, "unable to allocate memory");
+		internal_errorf("unable to allocate memory");
 	}
 
 	return aresize(ptr, nmemb * size, ap);
@@ -89,7 +89,7 @@ aresize(void *ptr, size_t size, Area *ap)
 
 	/* ensure that we don't overflow by allocating space for link */
 	if (size > SIZE_MAX - sizeof(struct link))
-		internal_errorf(1, "unable to allocate memory");
+		internal_errorf("unable to allocate memory");
 
 	l = P2L(ptr);
 	lprev = l->prev;
@@ -97,7 +97,7 @@ aresize(void *ptr, size_t size, Area *ap)
 
 	l2 = realloc(l, sizeof(struct link) + size);
 	if (l2 == NULL)
-		internal_errorf(1, "unable to allocate memory");
+		internal_errorf("unable to allocate memory");
 	if (lprev)
 		lprev->next = l2;
 	else
diff --git a/c_ksh.c b/c_ksh.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: c_ksh.c,v 1.57 2018/01/15 14:58:05 jca Exp $	*/
+/*	$OpenBSD: c_ksh.c,v 1.58 2018/01/16 22:52:32 jca Exp $	*/
 
 /*
  * built-in Korn commands: c_*
@@ -1273,7 +1273,7 @@ c_getopts(char **wp)
 	}
 
 	if (genv->loc->next == NULL) {
-		internal_errorf(0, "c_getopts: no argv");
+		internal_warningf("c_getopts: no argv");
 		return 1;
 	}
 	/* Which arguments are we parsing... */
diff --git a/c_ulimit.c b/c_ulimit.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: c_ulimit.c,v 1.24 2015/12/14 13:59:42 tb Exp $	*/
+/*	$OpenBSD: c_ulimit.c,v 1.26 2018/01/16 22:52:32 jca Exp $	*/
 
 /*
 	ulimit -- handle "ulimit" builtin
@@ -53,27 +53,13 @@ c_ulimit(char **wp)
 		{ "memory(kbytes)", RLIMIT_RSS, 1024, 'm' },
 		{ "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' },
 		{ "processes", RLIMIT_NPROC, 1, 'p' },
-#ifdef RLIMIT_VMEM
-		{ "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' },
-#endif /* RLIMIT_VMEM */
 		{ NULL }
 	};
-	static char	options[4 + NELEM(limits) * 2];
+	const char	*options = "HSat#f#c#d#s#l#m#n#p#";
 	int		how = SOFT | HARD;
 	const struct limits	*l;
 	int		optc, all = 0;
 
-	if (!options[0]) {
-		/* build options string on first call - yuck */
-		char *p = options;
-
-		*p++ = 'H'; *p++ = 'S'; *p++ = 'a';
-		for (l = limits; l->name; l++) {
-			*p++ = l->option;
-			*p++ = '#';
-		}
-		*p = '\0';
-	}
 	/* First check for -a, -H and -S. */
 	while ((optc = ksh_getopt(wp, &builtin_opt, options)) != -1)
 		switch (optc) {
@@ -111,7 +97,7 @@ c_ulimit(char **wp)
 			for (l = limits; l->name && l->option != optc; l++)
 				;
 			if (!l->name) {
-				internal_errorf(0, "ulimit: %c", optc);
+				internal_warningf("ulimit: %c", optc);
 				return 1;
 			}
 			if (builtin_opt.optarg) {
diff --git a/edit.c b/edit.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: edit.c,v 1.62 2018/01/15 14:58:05 jca Exp $	*/
+/*	$OpenBSD: edit.c,v 1.63 2018/01/16 22:52:32 jca Exp $	*/
 
 /*
  * Command line editing - common code
@@ -372,7 +372,7 @@ x_file_glob(int flags, const char *str, int slen, char ***wordsp)
 	source = s;
 	if (yylex(ONEWORD|UNESCAPE) != LWORD) {
 		source = sold;
-		internal_errorf(0, "fileglob: substitute error");
+		internal_warningf("fileglob: substitute error");
 		return 0;
 	}
 	source = sold;
@@ -616,12 +616,12 @@ x_try_array(const char *buf, int buflen, const char *want, int wantlen,
 
 	/* Try to find the array. */
 	if (asprintf(&name, "complete_%.*s_%d", cmdlen, cmd, n) < 0)
-		internal_errorf(1, "unable to allocate memory");
+		internal_errorf("unable to allocate memory");
 	v = global(name);
 	free(name);
 	if (~v->flag & (ISSET|ARRAY)) {
 		if (asprintf(&name, "complete_%.*s", cmdlen, cmd) < 0)
-			internal_errorf(1, "unable to allocate memory");
+			internal_errorf("unable to allocate memory");
 		v = global(name);
 		free(name);
 		if (~v->flag & (ISSET|ARRAY))
diff --git a/emacs.c b/emacs.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: emacs.c,v 1.83 2018/01/14 16:04:21 anton Exp $	*/
+/*	$OpenBSD: emacs.c,v 1.84 2018/01/16 17:17:18 jca Exp $	*/
 
 /*
  *  Emacs-like command line editing and history
@@ -1040,7 +1040,7 @@ x_redraw(int limit)
 		x_displen = xx_cols - 2;
 	}
 	xlp_valid = false;
-	cp = x_lastcp();
+	x_lastcp();
 	x_zots(xbp);
 	if (xbp != xbuf || xep > xlp)
 		limit = xx_cols;
diff --git a/eval.c b/eval.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: eval.c,v 1.58 2018/01/14 16:04:21 anton Exp $	*/
+/*	$OpenBSD: eval.c,v 1.59 2018/01/16 22:52:32 jca Exp $	*/
 
 /*
  * Expansion - quoting, separation, substitution, globbing
@@ -69,7 +69,7 @@ substitute(const char *cp, int f)
 	s->start = s->str = cp;
 	source = s;
 	if (yylex(ONEWORD) != LWORD)
-		internal_errorf(1, "substitute");
+		internal_errorf("substitute");
 	source = sold;
 	afree(s, ATEMP);
 	return evalstr(yylval.cp, f);
@@ -168,7 +168,7 @@ expand(char *cp,	/* input word */
 	size_t len;
 
 	if (cp == NULL)
-		internal_errorf(1, "expand(NULL)");
+		internal_errorf("expand(NULL)");
 	/* for alias, readonly, set, typeset commands */
 	if ((f & DOVACHECK) && is_wdvarassign(cp)) {
 		f &= ~(DOVACHECK|DOBLANK|DOGLOB|DOTILDE);
@@ -587,7 +587,7 @@ expand(char *cp,	/* input word */
 					char *p;
 
 					if ((p = strdup("")) == NULL)
-						internal_errorf(1, "unable "
+						internal_errorf("unable "
 						    "to allocate memory");
 					XPput(*wp, p);
 				}
diff --git a/exec.c b/exec.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: exec.c,v 1.71 2018/01/15 14:58:05 jca Exp $	*/
+/*	$OpenBSD: exec.c,v 1.72 2018/01/16 22:52:32 jca Exp $	*/
 
 /*
  * execute command tree
@@ -644,7 +644,7 @@ comexec(struct op *t, struct tbl *volatile tp, char **ap, volatile int flags,
 			/* NOTREACHED */
 		default:
 			quitenv(NULL);
-			internal_errorf(1, "CFUNC %d", i);
+			internal_errorf("CFUNC %d", i);
 		}
 		break;
 	    }
@@ -727,7 +727,7 @@ shcomexec(char **wp)
 
 	tp = ktsearch(&builtins, *wp, hash(*wp));
 	if (tp == NULL)
-		internal_errorf(1, "shcomexec: %s", *wp);
+		internal_errorf("shcomexec: %s", *wp);
 	return call_builtin(tp, wp);
 }
 
@@ -1221,7 +1221,7 @@ herein(const char *content, int sub)
 		s->start = s->str = content;
 		source = s;
 		if (yylex(ONEWORD|HEREDOC) != LWORD)
-			internal_errorf(1, "herein: yylex");
+			internal_errorf("herein: yylex");
 		source = osource;
 		shf_puts(evalstr(yylval.cp, 0), shf);
 	} else
@@ -1446,5 +1446,5 @@ static void
 dbteste_error(Test_env *te, int offset, const char *msg)
 {
 	te->flags |= TEF_ERROR;
-	internal_errorf(0, "dbteste_error: %s (offset %d)", msg, offset);
+	internal_warningf("dbteste_error: %s (offset %d)", msg, offset);
 }
diff --git a/io.c b/io.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: io.c,v 1.35 2016/03/20 00:01:21 krw Exp $	*/
+/*	$OpenBSD: io.c,v 1.36 2018/01/16 22:52:32 jca Exp $	*/
 
 /*
  * shell buffered IO and formatted output
@@ -86,21 +86,37 @@ bi_errorf(const char *fmt, ...)
 	}
 }
 
-/* Called when something that shouldn't happen does */
-void
-internal_errorf(int jump, const char *fmt, ...)
+static void
+internal_error_vwarn(const char *fmt, va_list va)
 {
-	va_list va;
-
 	error_prefix(true);
 	shf_fprintf(shl_out, "internal error: ");
-	va_start(va, fmt);
 	shf_vfprintf(shl_out, fmt, va);
-	va_end(va);
 	shf_putchar('\n', shl_out);
 	shf_flush(shl_out);
-	if (jump)
-		unwind(LERROR);
+}
+
+/* Warn when something that shouldn't happen does */
+void
+internal_warningf(const char *fmt, ...)
+{
+	va_list va;
+
+	va_start(va, fmt);
+	internal_error_vwarn(fmt, va);
+	va_end(va);
+}
+
+/* Warn and unwind when something that shouldn't happen does */
+__dead void
+internal_errorf(const char *fmt, ...)
+{
+	va_list va;
+
+	va_start(va, fmt);
+	internal_error_vwarn(fmt, va);
+	va_end(va);
+	unwind(LERROR);
 }
 
 /* used by error reporting functions to print "ksh: .kshrc[25]: " */
@@ -139,7 +155,7 @@ shprintf(const char *fmt, ...)
 	va_list va;
 
 	if (!shl_stdout_ok)
-		internal_errorf(1, "shl_stdout not valid");
+		internal_errorf("shl_stdout not valid");
 	va_start(va, fmt);
 	shf_vfprintf(shl_stdout, fmt, va);
 	va_end(va);
diff --git a/jobs.c b/jobs.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: jobs.c,v 1.58 2018/01/08 22:22:28 benno Exp $	*/
+/*	$OpenBSD: jobs.c,v 1.59 2018/01/16 22:52:32 jca Exp $	*/
 
 /*
  * Process and job control
@@ -411,7 +411,7 @@ exchild(struct op *t, int flags, volatile int *xerrok,
 	/* link process into jobs list */
 	if (flags&XPIPEI) {	/* continuing with a pipe */
 		if (!last_job)
-			internal_errorf(1,
+			internal_errorf(
 			    "exchild: XPIPEI and no last_job - pid %d",
 			    (int) procpid);
 		j = last_job;
@@ -522,7 +522,7 @@ exchild(struct op *t, int flags, volatile int *xerrok,
 		tty_close();
 		cleartraps();
 		execute(t, (flags & XERROK) | XEXEC, NULL); /* no return */
-		internal_errorf(0, "exchild: execute() returned");
+		internal_warningf("exchild: execute() returned");
 		unwind(LLEAVE);
 		/* NOTREACHED */
 	}
@@ -590,7 +590,7 @@ waitlast(void)
 		if (!j)
 			warningf(true, "waitlast: no last job");
 		else
-			internal_errorf(0, "waitlast: not started");
+			internal_warningf("waitlast: not started");
 		sigprocmask(SIG_SETMASK, &omask, NULL);
 		return 125; /* not so arbitrary, non-zero value */
 	}
@@ -931,7 +931,7 @@ j_set_async(Job *j)
 	if (async_job && (async_job->flags & (JF_KNOWN|JF_ZOMBIE)) == JF_ZOMBIE)
 		remove_job(async_job, "async");
 	if (!(j->flags & JF_STARTED)) {
-		internal_errorf(0, "j_async: job not started");
+		internal_warningf("j_async: job not started");
 		return;
 	}
 	async_job = j;
@@ -945,8 +945,8 @@ j_set_async(Job *j)
 		if (!oldest) {
 			/* XXX debugging */
 			if (!(async_job->flags & JF_ZOMBIE) || nzombie != 1) {
-				internal_errorf(0,
-				    "j_async: bad nzombie (%d)", nzombie);
+				internal_warningf("j_async: bad nzombie (%d)",
+				    nzombie);
 				nzombie = 0;
 			}
 			break;
@@ -1186,7 +1186,7 @@ check_job(Job *j)
 
 	/* XXX debugging (nasty - interrupt routine using shl_out) */
 	if (!(j->flags & JF_STARTED)) {
-		internal_errorf(0, "check_job: job started (flags 0x%x)",
+		internal_warningf("check_job: job started (flags 0x%x)",
 		    j->flags);
 		return;
 	}
@@ -1546,7 +1546,7 @@ remove_job(Job *j, const char *where)
 	for (; curr != NULL && curr != j; prev = &curr->next, curr = *prev)
 		;
 	if (curr != j) {
-		internal_errorf(0, "remove_job: job not found (%s)", where);
+		internal_warningf("remove_job: job not found (%s)", where);
 		return;
 	}
 	*prev = curr->next;
diff --git a/main.c b/main.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: main.c,v 1.88 2018/01/15 14:58:05 jca Exp $	*/
+/*	$OpenBSD: main.c,v 1.89 2018/01/16 22:52:32 jca Exp $	*/
 
 /*
  * startup, main loop, environments and error handling
@@ -494,7 +494,7 @@ include(const char *name, int argc, char **argv, int intr_ok)
 			unwind(i);
 			/* NOTREACHED */
 		default:
-			internal_errorf(1, "include: %d", i);
+			internal_errorf("include: %d", i);
 			/* NOTREACHED */
 		}
 	}
@@ -581,7 +581,7 @@ shell(Source *volatile s, volatile int toplevel)
 		default:
 			source = old_source;
 			quitenv(NULL);
-			internal_errorf(1, "shell: %d", i);
+			internal_errorf("shell: %d", i);
 			/* NOTREACHED */
 		}
 	}
diff --git a/misc.c b/misc.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: misc.c,v 1.67 2018/01/15 14:58:05 jca Exp $	*/
+/*	$OpenBSD: misc.c,v 1.68 2018/01/16 22:52:32 jca Exp $	*/
 
 /*
  * Miscellaneous functions
@@ -407,7 +407,7 @@ parse_args(char **argv,
 					break;
 				}
 			if (ele == NELEM(sh_options)) {
-				internal_errorf(1, "parse_args: `%c'", optc);
+				internal_errorf("parse_args: `%c'", optc);
 				return -1; /* not reached */
 			}
 		}
diff --git a/sh.h b/sh.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: sh.h,v 1.70 2018/01/15 14:58:05 jca Exp $	*/
+/*	$OpenBSD: sh.h,v 1.71 2018/01/16 22:52:32 jca Exp $	*/
 
 /*
  * Public Domain Bourne/Korn shell
@@ -464,8 +464,10 @@ void	warningf(bool, const char *, ...)
 	    __attribute__((__format__ (printf, 2, 3)));
 void	bi_errorf(const char *, ...)
 	    __attribute__((__format__ (printf, 1, 2)));
-void	internal_errorf(int, const char *, ...)
-	    __attribute__((__format__ (printf, 2, 3)));
+void	internal_errorf(const char *, ...)
+	    __attribute__((__noreturn__, __format__ (printf, 1, 2)));
+void	internal_warningf(const char *, ...)
+	    __attribute__((__format__ (printf, 1, 2)));
 void	error_prefix(int);
 void	shellf(const char *, ...)
 	    __attribute__((__format__ (printf, 1, 2)));
diff --git a/shf.c b/shf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: shf.c,v 1.31 2016/03/20 00:01:21 krw Exp $	*/
+/*	$OpenBSD: shf.c,v 1.32 2018/01/16 22:52:32 jca Exp $	*/
 
 /*
  *  Shell file I/O routines
@@ -100,7 +100,7 @@ shf_fdopen(int fd, int sflags, struct shf *shf)
 	}
 
 	if (!(sflags & (SHF_RD | SHF_WR)))
-		internal_errorf(1, "shf_fdopen: missing read/write");
+		internal_errorf("shf_fdopen: missing read/write");
 
 	if (shf) {
 		if (bsize) {
@@ -157,9 +157,9 @@ shf_reopen(int fd, int sflags, struct shf *shf)
 	}
 
 	if (!(sflags & (SHF_RD | SHF_WR)))
-		internal_errorf(1, "shf_reopen: missing read/write");
+		internal_errorf("shf_reopen: missing read/write");
 	if (!shf || !shf->buf || shf->bsize < bsize)
-		internal_errorf(1, "shf_reopen: bad shf/buf/bsize");
+		internal_errorf("shf_reopen: bad shf/buf/bsize");
 
 	/* assumes shf->buf and shf->bsize already set up */
 	shf->fd = fd;
@@ -189,7 +189,7 @@ shf_sopen(char *buf, int bsize, int sflags, struct shf *shf)
 	/* can't have a read+write string */
 	if (!(sflags & (SHF_RD | SHF_WR)) ||
 	    (sflags & (SHF_RD | SHF_WR)) == (SHF_RD | SHF_WR))
-		internal_errorf(1, "shf_sopen: flags 0x%x", sflags);
+		internal_errorf("shf_sopen: flags 0x%x", sflags);
 
 	if (!shf) {
 		shf = alloc(sizeof(struct shf), ATEMP);
@@ -282,7 +282,7 @@ shf_flush(struct shf *shf)
 		return (shf->flags & SHF_WR) ? EOF : 0;
 
 	if (shf->fd < 0)
-		internal_errorf(1, "shf_flush: no fd");
+		internal_errorf("shf_flush: no fd");
 
 	if (shf->flags & SHF_ERROR) {
 		errno = shf->errno_;
@@ -312,7 +312,7 @@ shf_emptybuf(struct shf *shf, int flags)
 	int ret = 0;
 
 	if (!(shf->flags & SHF_STRING) && shf->fd < 0)
-		internal_errorf(1, "shf_emptybuf: no fd");
+		internal_errorf("shf_emptybuf: no fd");
 
 	if (shf->flags & SHF_ERROR) {
 		errno = shf->errno_;
@@ -392,7 +392,7 @@ shf_fillbuf(struct shf *shf)
 		return 0;
 
 	if (shf->fd < 0)
-		internal_errorf(1, "shf_fillbuf: no fd");
+		internal_errorf("shf_fillbuf: no fd");
 
 	if (shf->flags & (SHF_EOF | SHF_ERROR)) {
 		if (shf->flags & SHF_ERROR)
@@ -438,10 +438,10 @@ shf_read(char *buf, int bsize, struct shf *shf)
 	int ncopy;
 
 	if (!(shf->flags & SHF_RD))
-		internal_errorf(1, "shf_read: flags %x", shf->flags);
+		internal_errorf("shf_read: flags %x", shf->flags);
 
 	if (bsize <= 0)
-		internal_errorf(1, "shf_read: bsize %d", bsize);
+		internal_errorf("shf_read: bsize %d", bsize);
 
 	while (bsize > 0) {
 		if (shf->rnleft == 0 &&
@@ -473,7 +473,7 @@ shf_getse(char *buf, int bsize, struct shf *shf)
 	char *orig_buf = buf;
 
 	if (!(shf->flags & SHF_RD))
-		internal_errorf(1, "shf_getse: flags %x", shf->flags);
+		internal_errorf("shf_getse: flags %x", shf->flags);
 
 	if (bsize <= 0)
 		return NULL;
@@ -508,7 +508,7 @@ int
 shf_getchar(struct shf *shf)
 {
 	if (!(shf->flags & SHF_RD))
-		internal_errorf(1, "shf_getchar: flags %x", shf->flags);
+		internal_errorf("shf_getchar: flags %x", shf->flags);
 
 	if (shf->rnleft == 0 && (shf_fillbuf(shf) == EOF || shf->rnleft == 0))
 		return EOF;
@@ -523,7 +523,7 @@ int
 shf_ungetc(int c, struct shf *shf)
 {
 	if (!(shf->flags & SHF_RD))
-		internal_errorf(1, "shf_ungetc: flags %x", shf->flags);
+		internal_errorf("shf_ungetc: flags %x", shf->flags);
 
 	if ((shf->flags & SHF_ERROR) || c == EOF ||
 	    (shf->rp == shf->buf && shf->rnleft))
@@ -558,7 +558,7 @@ int
 shf_putchar(int c, struct shf *shf)
 {
 	if (!(shf->flags & SHF_WR))
-		internal_errorf(1, "shf_putchar: flags %x", shf->flags);
+		internal_errorf("shf_putchar: flags %x", shf->flags);
 
 	if (c == EOF)
 		return EOF;
@@ -568,7 +568,7 @@ shf_putchar(int c, struct shf *shf)
 		int n;
 
 		if (shf->fd < 0)
-			internal_errorf(1, "shf_putchar: no fd");
+			internal_errorf("shf_putchar: no fd");
 		if (shf->flags & SHF_ERROR) {
 			errno = shf->errno_;
 			return EOF;
@@ -614,10 +614,10 @@ shf_write(const char *buf, int nbytes, struct shf *shf)
 	int ncopy;
 
 	if (!(shf->flags & SHF_WR))
-		internal_errorf(1, "shf_write: flags %x", shf->flags);
+		internal_errorf("shf_write: flags %x", shf->flags);
 
 	if (nbytes < 0)
-		internal_errorf(1, "shf_write: nbytes %d", nbytes);
+		internal_errorf("shf_write: nbytes %d", nbytes);
 
 	/* Don't buffer if buffer is empty and we're writting a large amount. */
 	if ((ncopy = shf->wnleft) &&
@@ -687,7 +687,7 @@ shf_snprintf(char *buf, int bsize, const char *fmt, ...)
 	int n;
 
 	if (!buf || bsize <= 0)
-		internal_errorf(1, "shf_snprintf: buf %lx, bsize %d",
+		internal_errorf("shf_snprintf: buf %lx, bsize %d",
 			(long) buf, bsize);
 
 	shf_sopen(buf, bsize, SHF_WR, &shf);
diff --git a/table.c b/table.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: table.c,v 1.24 2017/12/27 13:02:57 millert Exp $	*/
+/*	$OpenBSD: table.c,v 1.25 2018/01/16 22:52:32 jca Exp $	*/
 
 /*
  * dynamic hashed associative table for commands and variables
@@ -128,7 +128,7 @@ ktenter(struct table *tp, const char *n, unsigned int h)
 		if (tp->size <= INT_MAX/2)
 			texpand(tp, 2*tp->size);
 		else
-			internal_errorf(1, "too many vars");
+			internal_errorf("too many vars");
 		goto Search;
 	}
 
diff --git a/trap.c b/trap.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: trap.c,v 1.30 2016/03/17 23:33:23 mmcc Exp $	*/
+/*	$OpenBSD: trap.c,v 1.31 2018/01/16 22:52:32 jca Exp $	*/
 
 /*
  * signal handling
@@ -402,7 +402,7 @@ setexecsig(Trap *p, int restore)
 {
 	/* XXX debugging */
 	if (!(p->flags & (TF_ORIG_IGN|TF_ORIG_DFL)))
-		internal_errorf(1, "setexecsig: unset signal %d(%s)",
+		internal_errorf("setexecsig: unset signal %d(%s)",
 		    p->signal, p->name);
 
 	/* restore original value for exec'd kids */
diff --git a/tree.c b/tree.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: tree.c,v 1.30 2018/01/06 16:28:58 millert Exp $	*/
+/*	$OpenBSD: tree.c,v 1.31 2018/01/16 22:52:32 jca Exp $	*/
 
 /*
  * command tree climbing
@@ -549,7 +549,7 @@ wdscan(const char *wp, int c)
 				nest--;
 			break;
 		default:
-			internal_errorf(0,
+			internal_warningf(
 			    "wdscan: unknown char 0x%x (carrying on)",
 			    wp[-1]);
 		}
diff --git a/var.c b/var.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: var.c,v 1.64 2018/01/15 14:58:05 jca Exp $	*/
+/*	$OpenBSD: var.c,v 1.65 2018/01/16 22:52:32 jca Exp $	*/
 
 #include <sys/stat.h>
 
@@ -366,7 +366,7 @@ setstr(struct tbl *vq, const char *s, int error_ok)
 			/* debugging */
 			if (s >= vq->val.s &&
 			    s <= vq->val.s + strlen(vq->val.s))
-				internal_errorf(true,
+				internal_errorf(
 				    "setstr: %s=%s: assigning to self",
 				    vq->name, s);
 			afree(vq->val.s, vq->areap);
diff --git a/vi.c b/vi.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vi.c,v 1.54 2018/01/13 02:06:54 schwarze Exp $	*/
+/*	$OpenBSD: vi.c,v 1.55 2018/01/16 22:52:32 jca Exp $	*/
 
 /*
  *	vi command editing
@@ -1669,7 +1669,7 @@ grabhist(int save, int n)
 	}
 	(void) histnum(n);
 	if ((hptr = *histpos()) == NULL) {
-		internal_errorf(0, "grabhist: bad history array");
+		internal_warningf("grabhist: bad history array");
 		return -1;
 	}
 	if (save)