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: 7da390be9282748fdbe93ca891c16f37bf2c59cd
parent: 663ad4a6f5d0ebdd0438dda48cfa529440861aec
author: Brian Callahan <bcallah@openbsd.org>
date:   Thu, 11 Jan 2018 22:00:17 -0500
Sync with OpenBSD. Add configure check for -w flag; use it if your compiler has it.
MCVS/Entries84++++-----
MNOTES8+-
MPROJECTS49+----
MREADME.md2+-
Mconfigure27++-
Memacs.c198++++++++++----------
Mjobs.c30+--
7 files changed, 187 insertions(+), 211 deletions(-)
diff --git a/CVS/Entries b/CVS/Entries
@@ -1,46 +1,46 @@
-/CONTRIBUTORS/1.10/Sun Jan  7 20:03:32 2018//
-/LEGAL/1.2/Sun Jan  7 20:03:32 2018//
-/Makefile/1.38/Sun Jan  7 23:21:17 2018//
-/NOTES/1.14/Sun Jan  7 20:03:32 2018//
-/PROJECTS/1.8/Sun Jan  7 20:03:32 2018//
-/README/1.16/Sun Jan  7 23:21:17 2018//
-/alloc.c/1.18/Sun Jan  7 20:03:32 2018//
-/c_ksh.c/1.56/Sun Jan  7 23:21:17 2018//
-/c_sh.c/1.62/Sun Jan  7 20:03:32 2018//
-/c_test.c/1.24/Sun Jan  7 20:03:32 2018//
-/c_test.h/1.4/Sun Jan  7 20:03:32 2018//
-/c_ulimit.c/1.24/Sun Jan  7 20:03:32 2018//
 /config.h/1.17/Result of merge//
-/edit.c/1.61/Sun Jan  7 23:21:17 2018//
-/edit.h/1.11/Sun Jan  7 20:03:32 2018//
-/emacs.c/1.81/Result of merge//
-/eval.c/1.57/Sun Jan  7 23:21:17 2018//
-/exec.c/1.70/Sun Jan  7 20:03:32 2018//
-/expand.h/1.15/Sun Jan  7 23:21:17 2018//
-/expr.c/1.32/Sun Jan  7 20:03:32 2018//
 /history.c/1.78/Result of merge//
-/io.c/1.35/Sun Jan  7 20:03:32 2018//
-/jobs.c/1.57/Sun Jan  7 23:21:17 2018//
-/ksh.1/1.197/Sun Jan  7 20:03:32 2018//
-/lex.c/1.77/Sun Jan  7 23:21:18 2018//
-/lex.h/1.20/Sun Jan  7 23:21:18 2018//
-/mail.c/1.22/Sun Jan  7 20:03:32 2018//
 /main.c/1.86/Result of merge//
-/misc.c/1.65/Sun Jan  7 23:21:18 2018//
-/path.c/1.22/Sun Jan  7 23:21:18 2018//
-/sh.1/1.146/Sun Jan  7 20:03:32 2018//
-/sh.h/1.68/Sun Jan  7 23:21:18 2018//
-/shf.c/1.31/Sun Jan  7 20:03:32 2018//
-/shf.h/1.8/Sun Jan  7 20:03:32 2018//
-/syn.c/1.38/Sun Jan  7 20:03:32 2018//
-/table.c/1.24/Sun Jan  7 20:03:32 2018//
-/table.h/1.13/Sun Jan  7 20:03:32 2018//
-/trap.c/1.30/Sun Jan  7 20:03:32 2018//
-/tree.c/1.30/Sun Jan  7 23:21:18 2018//
-/tree.h/1.12/Sun Jan  7 20:03:32 2018//
-/tty.c/1.16/Sun Jan  7 20:03:32 2018//
-/tty.h/1.6/Sun Jan  7 20:03:32 2018//
-/var.c/1.63/Sun Jan  7 23:21:18 2018//
-/version.c/1.12/Sun Jan  7 20:03:32 2018//
-/vi.c/1.53/Sun Jan  7 23:21:18 2018//
+/CONTRIBUTORS/1.10/Fri Jan 12 00:53:51 2018//
+/LEGAL/1.2/Fri Jan 12 00:53:51 2018//
+/Makefile/1.38/Fri Jan 12 00:54:17 2018//
+/NOTES/1.15/Fri Jan 12 00:54:17 2018//
+/PROJECTS/1.9/Fri Jan 12 00:54:17 2018//
+/alloc.c/1.18/Fri Jan 12 00:53:51 2018//
+/c_ksh.c/1.56/Fri Jan 12 00:53:51 2018//
+/c_sh.c/1.62/Fri Jan 12 00:53:51 2018//
+/c_test.c/1.24/Fri Jan 12 00:53:51 2018//
+/c_test.h/1.4/Fri Jan 12 00:53:51 2018//
+/c_ulimit.c/1.24/Fri Jan 12 00:53:51 2018//
+/edit.c/1.61/Fri Jan 12 00:53:51 2018//
+/edit.h/1.11/Fri Jan 12 00:53:51 2018//
+/emacs.c/1.82/Result of merge//
+/eval.c/1.57/Fri Jan 12 00:53:51 2018//
+/exec.c/1.70/Fri Jan 12 00:53:51 2018//
+/expand.h/1.15/Fri Jan 12 00:53:51 2018//
+/expr.c/1.32/Fri Jan 12 00:53:51 2018//
+/io.c/1.35/Fri Jan 12 00:53:51 2018//
+/jobs.c/1.58/Fri Jan 12 00:54:18 2018//
+/ksh.1/1.197/Fri Jan 12 00:53:51 2018//
+/lex.c/1.77/Fri Jan 12 00:53:51 2018//
+/lex.h/1.20/Fri Jan 12 00:53:51 2018//
+/mail.c/1.22/Fri Jan 12 00:53:51 2018//
+/misc.c/1.65/Fri Jan 12 00:53:51 2018//
+/path.c/1.22/Fri Jan 12 00:53:51 2018//
+/sh.1/1.146/Fri Jan 12 00:53:51 2018//
+/sh.h/1.68/Fri Jan 12 00:53:51 2018//
+/shf.c/1.31/Fri Jan 12 00:53:51 2018//
+/shf.h/1.8/Fri Jan 12 00:53:51 2018//
+/syn.c/1.38/Fri Jan 12 00:53:51 2018//
+/table.c/1.24/Fri Jan 12 00:53:51 2018//
+/table.h/1.13/Fri Jan 12 00:53:51 2018//
+/trap.c/1.30/Fri Jan 12 00:53:51 2018//
+/tree.c/1.30/Fri Jan 12 00:53:51 2018//
+/tree.h/1.12/Fri Jan 12 00:53:51 2018//
+/tty.c/1.16/Fri Jan 12 00:53:51 2018//
+/tty.h/1.6/Fri Jan 12 00:53:51 2018//
+/var.c/1.63/Fri Jan 12 00:53:51 2018//
+/version.c/1.12/Fri Jan 12 00:53:51 2018//
+/vi.c/1.53/Fri Jan 12 00:53:51 2018//
+/README/1.16/Fri Jan 12 02:59:19 2018//
 D
diff --git a/NOTES b/NOTES
@@ -1,4 +1,4 @@
-$OpenBSD: NOTES,v 1.14 2016/01/29 11:50:40 tb Exp $
+$OpenBSD: NOTES,v 1.15 2018/01/08 13:39:06 jca Exp $
 
 General features of at&t ksh88 that are not (yet) in pdksh:
     - exported aliases and functions (not in ksh93).
@@ -6,7 +6,6 @@ General features of at&t ksh88 that are not (yet) in pdksh:
     - signals/traps not cleared during functions.
     - trap DEBUG, local ERR and EXIT traps in functions.
     - ERRNO parameter.
-    - doesn't have posix file globbing (eg, [[:alpha:]], etc.).
     - use of an `agent' to execute unreadable/setuid/setgid shell scripts
       (don't ask).
     - read/select aren't hooked in to the command line editor
@@ -34,7 +33,6 @@ Known bugs (see also BUG-REPORTS and PROJECTS files):
 	  an exit, but not sure.
 	- `echo foo | read bar; echo $bar' prints foo in at&t ksh, nothing
 	  in pdksh (ie, the read is done in a separate process in pdksh).
-    Misc:
 
 Known problems not caused by ksh:
     - after stoping a job, emacs/vi is not re-entered.  Hitting return
@@ -249,15 +247,13 @@ POSIX sh questions (references are to POSIX 1003.2-1992)
 	  (eg, echo $((  ))).  at&t ksh (and now pdksh) echo 0.
 	  Same question goes for `test "" -eq 0' - does this generate an error
 	  or, if not, what is the exit code?
-	- should tilde expansion occur after :'s in the word part of ${..=..}?
-	  (me thinks it should)
 	- if a signal is received during the execution of a built-in,
 	  does the builtin command exit or the whole shell?
 	- is it legal to execute last command of pipeline in current
 	  execution environment (eg, can "echo foo | read bar" set
 	  bar?)
 	- what action should be taken if there is an error doing a dup due
-	  to system limits (eg, not enough feil destriptors): is this
+	  to system limits (eg, not enough file destriptors): is this
 	  a "redirection error" (in which case a script will exit iff the
 	  error occured while executing a special built-in)?
 	  IMHO, shell should exit script.  Couldn't find a blanket statement
diff --git a/PROJECTS b/PROJECTS
@@ -1,4 +1,4 @@
-$OpenBSD: PROJECTS,v 1.8 2015/09/14 09:42:33 nicm Exp $
+$OpenBSD: PROJECTS,v 1.9 2018/01/08 12:08:17 jca Exp $
 
 Things to be done in pdksh (see also the NOTES file):
 
@@ -22,31 +22,11 @@ Things to be done in pdksh (see also the NOTES file):
 
       (ulimit also needs to be examined to check that it fits the posix style)
 
-    * test suite
-      Ideally, as the builtin utilities are being POSIXized, short tests
-      should be written to be used in regression testing.  The tests
-      directory contains some tests, but many more need to be written.
-
-    * internationalization
-      Need to handle with the LANG and LC_* environment variables.  This
-      involves changes to ensure <ctype.h> macros are being used (currently
-      uses its own macros in many places), figuring out how to deal with
-      bases (for integer arithmetic, eg, 12#1A), and (the nasty one) doing
-      string look ups for error messages, etc..  It probably isn't worth
-      translating strings to other languages yet as the code is likely
-      to change a lot in the near future, but it would be good to have the
-      code set up so string tables can be used.
-
     * trap code
 	* add the DEBUG trap.
 	* fix up signal handling code.  In particular, fatal vs tty signals,
 	  have signal routine to call to check for pending/fatal traps, etc.
 
-    * parsing
-	* the time keyword needs to be hacked to accept options (!) since
-	  POSIX says it shall accept the -p option and must skip a -- argument
-	  (end of options).  Yuck.
-
     * lexing
       the lexing may need a re-write since it currently doesn't parse $( .. ),
       $(( .. )), (( ... )) properly.
@@ -68,30 +48,10 @@ Things to be done in pdksh (see also the NOTES file):
       in general, treatment of OPTIND/OPTARG,
 
     * history
-      There are two versions of the history code, COMPLEX_HISTORY and
-      EASY_HISTORY, which need to be merged.  COMPLEX does at&t style history
-      where the history file is written after each command and checked when
-      ever looking through the history (in case another shell has added
-      something).  EASY simply reads the history file at startup and writes
-      it before exiting.
-	* re-write the COMPLEX_HISTORY code so mmap() not needed (currently
-	  can't be used on machines without mmap()).
-	* Add multiline knowledge to COMPLEX_HISTORY (see EASY_HISTORY
-	  stuff).
-	* change COMPLEX_HISTORY code so concurrent history files are
-	  controlled by an option (set -o history-concurrent?).  Delete
-	  the EASY_HISTORY code.
+	* Add multiline knowledge
 	* bring history code up to POSIX standards (see POSIX description
 	  of fc, etc.).
 
-    * documentation
-      Some sort of tutorial with examples would be good.  Texinfo is probably
-      the best medium for this.  Also, the man page could be converted to
-      texinfo (if the tutorial and man page  are put in the same texinfo
-      page, they should be somewhat distinct - i.e., the tutorial should
-      be a separate thread - but there should be cross references between the
-      two).
-
     * miscellaneous
 	* POSIX specifies what happens when various kinds of errors occur
 	  in special built-ins commands vs regular commands (builtin or
@@ -104,8 +64,3 @@ Things to be done in pdksh (see also the NOTES file):
 	* merge the emacs and vi code (should reduce the size of the shell and
 	  make maintenance easier); handle SIGWINCH while editing a line.
 	  [John Rochester is working on the merge]
-
-	* add POSIX globbing (eg, [[:alnum:]]), see POSIX.2:2.8.3.2.
-
-	* teach shf_vfprintf() about long long's (%lld); also make %p use
-	  long longs if appropriate.
diff --git a/README.md b/README.md
@@ -40,4 +40,4 @@ The rest are BSD or ISC licensed.
 
 Get a tarball
 -------------
-http://devio.us/~bcallah/oksh/oksh-20180108.tar.gz
+http://devio.us/~bcallah/oksh/oksh-20180111.tar.gz
diff --git a/configure b/configure
@@ -192,6 +192,21 @@ EOF
   fi
 }
 
+wflagcheck() {
+  cat << EOF > conftest.c
+int main(void){return 0;}
+EOF
+  $cc -w -o conftest conftest.c > /dev/null 2> conftest.err
+  grep ':' conftest.err > /dev/null 2>&1
+  if [ $? -eq 0 ] ; then
+    rm -f conftest conftest.err conftest.c
+    return 1
+  else
+    rm -f conftest conftest.err conftest.c
+    return 0
+  fi
+}
+
 if [ ! -z "$PREFIX" ] ; then
 prefix="$PREFIX"
 else
@@ -223,7 +238,6 @@ do
 	exit 1
 	;;
     *)
-	echo "Unknown option: $opt"
 	;;
   esac
 done
@@ -244,6 +258,15 @@ else
   echo "$cc"
 fi
 
+printf "checking for -w compiler flag... "
+wflagcheck
+if [ $? -ne 0 ] ; then
+  echo "no"
+else
+  cflags="$cflags -w"
+  echo "yes"
+fi
+
 printf "checking for OS... "
 os=`uname -s`
 echo "$os"
@@ -352,6 +375,7 @@ else
   echo "yes"
 fi
 
+printf "creating Makefile... "
 cat << EOF > Makefile
 # This Makefile automatically generated by configure.
 
@@ -388,3 +412,4 @@ clean:
 distclean: clean
 	rm -f Makefile pconfig.h
 EOF
+echo "done"
diff --git a/emacs.c b/emacs.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: emacs.c,v 1.81 2018/01/07 19:18:56 millert Exp $	*/
+/*	$OpenBSD: emacs.c,v 1.82 2018/01/08 13:01:31 millert Exp $	*/
 
 /*
  *  Emacs-like command line editing and history
@@ -1327,14 +1327,14 @@ kb_add_string(void *func, void *args, char *str)
 }
 
 static struct kb_entry *
-kb_add(void *func, void *args, ...)
+kb_add(void *func, ...)
 {
 	va_list			ap;
 	unsigned char		ch;
 	unsigned int		i;
 	char			line[LINE + 1];
 
-	va_start(ap, args);
+	va_start(ap, func);
 	for (i = 0; i < sizeof(line) - 1; i++) {
 		ch = va_arg(ap, unsigned int);
 		if (ch == 0)
@@ -1344,7 +1344,7 @@ kb_add(void *func, void *args, ...)
 	va_end(ap);
 	line[i] = '\0';
 
-	return (kb_add_string(func, args, line));
+	return (kb_add_string(func, NULL, line));
 }
 
 static void
@@ -1455,109 +1455,109 @@ x_init_emacs(void)
 	TAILQ_INIT(&kblist);
 
 	/* man page order */
-	kb_add(x_abort,			NULL, CTRL('G'), 0);
-	kb_add(x_mv_back,		NULL, CTRL('B'), 0);
-	kb_add(x_mv_back,		NULL, CTRL('X'), CTRL('D'), 0);
-	kb_add(x_mv_bword,		NULL, CTRL('['), 'b', 0);
-	kb_add(x_beg_hist,		NULL, CTRL('['), '<', 0);
-	kb_add(x_mv_begin,		NULL, CTRL('A'), 0);
-	kb_add(x_fold_capitalize,	NULL, CTRL('['), 'C', 0);
-	kb_add(x_fold_capitalize,	NULL, CTRL('['), 'c', 0);
-	kb_add(x_comment,		NULL, CTRL('['), '#', 0);
-	kb_add(x_complete,		NULL, CTRL('['), CTRL('['), 0);
-	kb_add(x_comp_comm,		NULL, CTRL('X'), CTRL('['), 0);
-	kb_add(x_comp_file,		NULL, CTRL('['), CTRL('X'), 0);
-	kb_add(x_comp_list,		NULL, CTRL('I'), 0);
-	kb_add(x_comp_list,		NULL, CTRL('['), '=', 0);
-	kb_add(x_del_back,		NULL, CTRL('?'), 0);
-	kb_add(x_del_back,		NULL, CTRL('H'), 0);
-	kb_add(x_del_char,		NULL, CTRL('['), '[', '3', '~', 0); /* delete */
-	kb_add(x_del_bword,		NULL, CTRL('W'), 0);
-	kb_add(x_del_bword,		NULL, CTRL('['), CTRL('?'), 0);
-	kb_add(x_del_bword,		NULL, CTRL('['), CTRL('H'), 0);
-	kb_add(x_del_bword,		NULL, CTRL('['), 'h', 0);
-	kb_add(x_del_fword,		NULL, CTRL('['), 'd', 0);
-	kb_add(x_next_com,		NULL, CTRL('N'), 0);
-	kb_add(x_next_com,		NULL, CTRL('X'), 'B', 0);
-	kb_add(x_fold_lower,		NULL, CTRL('['), 'L', 0);
-	kb_add(x_fold_lower,		NULL, CTRL('['), 'l', 0);
-	kb_add(x_end_hist,		NULL, CTRL('['), '>', 0);
-	kb_add(x_mv_end,		NULL, CTRL('E'), 0);
+	kb_add(x_abort,			CTRL('G'), 0);
+	kb_add(x_mv_back,		CTRL('B'), 0);
+	kb_add(x_mv_back,		CTRL('X'), CTRL('D'), 0);
+	kb_add(x_mv_bword,		CTRL('['), 'b', 0);
+	kb_add(x_beg_hist,		CTRL('['), '<', 0);
+	kb_add(x_mv_begin,		CTRL('A'), 0);
+	kb_add(x_fold_capitalize,	CTRL('['), 'C', 0);
+	kb_add(x_fold_capitalize,	CTRL('['), 'c', 0);
+	kb_add(x_comment,		CTRL('['), '#', 0);
+	kb_add(x_complete,		CTRL('['), CTRL('['), 0);
+	kb_add(x_comp_comm,		CTRL('X'), CTRL('['), 0);
+	kb_add(x_comp_file,		CTRL('['), CTRL('X'), 0);
+	kb_add(x_comp_list,		CTRL('I'), 0);
+	kb_add(x_comp_list,		CTRL('['), '=', 0);
+	kb_add(x_del_back,		CTRL('?'), 0);
+	kb_add(x_del_back,		CTRL('H'), 0);
+	kb_add(x_del_char,		CTRL('['), '[', '3', '~', 0); /* delete */
+	kb_add(x_del_bword,		CTRL('W'), 0);
+	kb_add(x_del_bword,		CTRL('['), CTRL('?'), 0);
+	kb_add(x_del_bword,		CTRL('['), CTRL('H'), 0);
+	kb_add(x_del_bword,		CTRL('['), 'h', 0);
+	kb_add(x_del_fword,		CTRL('['), 'd', 0);
+	kb_add(x_next_com,		CTRL('N'), 0);
+	kb_add(x_next_com,		CTRL('X'), 'B', 0);
+	kb_add(x_fold_lower,		CTRL('['), 'L', 0);
+	kb_add(x_fold_lower,		CTRL('['), 'l', 0);
+	kb_add(x_end_hist,		CTRL('['), '>', 0);
+	kb_add(x_mv_end,		CTRL('E'), 0);
 	/* how to handle: eot: ^_, underneath copied from original keybindings */
-	kb_add(x_end_of_text,		NULL, CTRL('_'), 0);
-	kb_add(x_eot_del,		NULL, CTRL('D'), 0);
+	kb_add(x_end_of_text,		CTRL('_'), 0);
+	kb_add(x_eot_del,		CTRL('D'), 0);
 	/* error */
-	kb_add(x_xchg_point_mark,	NULL, CTRL('X'), CTRL('X'), 0);
-	kb_add(x_expand,		NULL, CTRL('['), '*', 0);
-	kb_add(x_mv_forw,		NULL, CTRL('F'), 0);
-	kb_add(x_mv_forw,		NULL, CTRL('X'), 'C', 0);
-	kb_add(x_mv_fword,		NULL, CTRL('['), 'f', 0);
-	kb_add(x_goto_hist,		NULL, CTRL('['), 'g', 0);
+	kb_add(x_xchg_point_mark,	CTRL('X'), CTRL('X'), 0);
+	kb_add(x_expand,		CTRL('['), '*', 0);
+	kb_add(x_mv_forw,		CTRL('F'), 0);
+	kb_add(x_mv_forw,		CTRL('X'), 'C', 0);
+	kb_add(x_mv_fword,		CTRL('['), 'f', 0);
+	kb_add(x_goto_hist,		CTRL('['), 'g', 0);
 	/* kill-line */
-	kb_add(x_kill,			NULL, CTRL('K'), 0);
-	kb_add(x_enumerate,		NULL, CTRL('['), '?', 0);
-	kb_add(x_list_comm,		NULL, CTRL('X'), '?', 0);
-	kb_add(x_list_file,		NULL, CTRL('X'), CTRL('Y'), 0);
-	kb_add(x_newline,		NULL, CTRL('J'), 0);
-	kb_add(x_newline,		NULL, CTRL('M'), 0);
-	kb_add(x_nl_next_com,		NULL, CTRL('O'), 0);
+	kb_add(x_kill,			CTRL('K'), 0);
+	kb_add(x_enumerate,		CTRL('['), '?', 0);
+	kb_add(x_list_comm,		CTRL('X'), '?', 0);
+	kb_add(x_list_file,		CTRL('X'), CTRL('Y'), 0);
+	kb_add(x_newline,		CTRL('J'), 0);
+	kb_add(x_newline,		CTRL('M'), 0);
+	kb_add(x_nl_next_com,		CTRL('O'), 0);
 	/* no-op */
-	kb_add(x_prev_histword,		NULL, CTRL('['), '.', 0);
-	kb_add(x_prev_histword,		NULL, CTRL('['), '_', 0);
+	kb_add(x_prev_histword,		CTRL('['), '.', 0);
+	kb_add(x_prev_histword,		CTRL('['), '_', 0);
 	/* how to handle: quote: ^^ */
-	kb_add(x_literal,		NULL, CTRL('^'), 0);
-	kb_add(x_draw_line,		NULL, CTRL('L'), 0);
-	kb_add(x_search_char_back,	NULL, CTRL('['), CTRL(']'), 0);
-	kb_add(x_search_char_forw,	NULL, CTRL(']'), 0);
-	kb_add(x_search_hist,		NULL, CTRL('R'), 0);
-	kb_add(x_set_mark,		NULL, CTRL('['), ' ', 0);
-	kb_add(x_transpose,		NULL, CTRL('T'), 0);
-	kb_add(x_prev_com,		NULL, CTRL('P'), 0);
-	kb_add(x_prev_com,		NULL, CTRL('X'), 'A', 0);
-	kb_add(x_fold_upper,		NULL, CTRL('['), 'U', 0);
-	kb_add(x_fold_upper,		NULL, CTRL('['), 'u', 0);
-	kb_add(x_literal,		NULL, CTRL('V'), 0);
-	kb_add(x_yank,			NULL, CTRL('Y'), 0);
-	kb_add(x_meta_yank,		NULL, CTRL('['), 'y', 0);
+	kb_add(x_literal,		CTRL('^'), 0);
+	kb_add(x_draw_line,		CTRL('L'), 0);
+	kb_add(x_search_char_back,	CTRL('['), CTRL(']'), 0);
+	kb_add(x_search_char_forw,	CTRL(']'), 0);
+	kb_add(x_search_hist,		CTRL('R'), 0);
+	kb_add(x_set_mark,		CTRL('['), ' ', 0);
+	kb_add(x_transpose,		CTRL('T'), 0);
+	kb_add(x_prev_com,		CTRL('P'), 0);
+	kb_add(x_prev_com,		CTRL('X'), 'A', 0);
+	kb_add(x_fold_upper,		CTRL('['), 'U', 0);
+	kb_add(x_fold_upper,		CTRL('['), 'u', 0);
+	kb_add(x_literal,		CTRL('V'), 0);
+	kb_add(x_yank,			CTRL('Y'), 0);
+	kb_add(x_meta_yank,		CTRL('['), 'y', 0);
 	/* man page ends here */
 
 	/* arrow keys */
-	kb_add(x_prev_com,		NULL, CTRL('['), '[', 'A', 0); /* up */
-	kb_add(x_next_com,		NULL, CTRL('['), '[', 'B', 0); /* down */
-	kb_add(x_mv_forw,		NULL, CTRL('['), '[', 'C', 0); /* right */
-	kb_add(x_mv_back,		NULL, CTRL('['), '[', 'D', 0); /* left */
-	kb_add(x_prev_com,		NULL, CTRL('['), 'O', 'A', 0); /* up */
-	kb_add(x_next_com,		NULL, CTRL('['), 'O', 'B', 0); /* down */
-	kb_add(x_mv_forw,		NULL, CTRL('['), 'O', 'C', 0); /* right */
-	kb_add(x_mv_back,		NULL, CTRL('['), 'O', 'D', 0); /* left */
+	kb_add(x_prev_com,		CTRL('['), '[', 'A', 0); /* up */
+	kb_add(x_next_com,		CTRL('['), '[', 'B', 0); /* down */
+	kb_add(x_mv_forw,		CTRL('['), '[', 'C', 0); /* right */
+	kb_add(x_mv_back,		CTRL('['), '[', 'D', 0); /* left */
+	kb_add(x_prev_com,		CTRL('['), 'O', 'A', 0); /* up */
+	kb_add(x_next_com,		CTRL('['), 'O', 'B', 0); /* down */
+	kb_add(x_mv_forw,		CTRL('['), 'O', 'C', 0); /* right */
+	kb_add(x_mv_back,		CTRL('['), 'O', 'D', 0); /* left */
 
 	/* more navigation keys */
-	kb_add(x_mv_begin,		NULL, CTRL('['), '[', 'H', 0); /* home */
-	kb_add(x_mv_end,		NULL, CTRL('['), '[', 'F', 0); /* end */
-	kb_add(x_mv_begin,		NULL, CTRL('['), 'O', 'H', 0); /* home */
-	kb_add(x_mv_end,		NULL, CTRL('['), 'O', 'F', 0); /* end */
-	kb_add(x_mv_begin,		NULL, CTRL('['), '[', '1', '~', 0); /* home */
-	kb_add(x_mv_end,		NULL, CTRL('['), '[', '4', '~', 0); /* end */
-	kb_add(x_mv_begin,		NULL, CTRL('['), '[', '7', '~', 0); /* home */
-	kb_add(x_mv_end,		NULL, CTRL('['), '[', '8', '~', 0); /* end */
+	kb_add(x_mv_begin,		CTRL('['), '[', 'H', 0); /* home */
+	kb_add(x_mv_end,		CTRL('['), '[', 'F', 0); /* end */
+	kb_add(x_mv_begin,		CTRL('['), 'O', 'H', 0); /* home */
+	kb_add(x_mv_end,		CTRL('['), 'O', 'F', 0); /* end */
+	kb_add(x_mv_begin,		CTRL('['), '[', '1', '~', 0); /* home */
+	kb_add(x_mv_end,		CTRL('['), '[', '4', '~', 0); /* end */
+	kb_add(x_mv_begin,		CTRL('['), '[', '7', '~', 0); /* home */
+	kb_add(x_mv_end,		CTRL('['), '[', '8', '~', 0); /* end */
 
 	/* can't be bound */
-	kb_add(x_set_arg,		NULL, CTRL('['), '0', 0);
-	kb_add(x_set_arg,		NULL, CTRL('['), '1', 0);
-	kb_add(x_set_arg,		NULL, CTRL('['), '2', 0);
-	kb_add(x_set_arg,		NULL, CTRL('['), '3', 0);
-	kb_add(x_set_arg,		NULL, CTRL('['), '4', 0);
-	kb_add(x_set_arg,		NULL, CTRL('['), '5', 0);
-	kb_add(x_set_arg,		NULL, CTRL('['), '6', 0);
-	kb_add(x_set_arg,		NULL, CTRL('['), '7', 0);
-	kb_add(x_set_arg,		NULL, CTRL('['), '8', 0);
-	kb_add(x_set_arg,		NULL, CTRL('['), '9', 0);
+	kb_add(x_set_arg,		CTRL('['), '0', 0);
+	kb_add(x_set_arg,		CTRL('['), '1', 0);
+	kb_add(x_set_arg,		CTRL('['), '2', 0);
+	kb_add(x_set_arg,		CTRL('['), '3', 0);
+	kb_add(x_set_arg,		CTRL('['), '4', 0);
+	kb_add(x_set_arg,		CTRL('['), '5', 0);
+	kb_add(x_set_arg,		CTRL('['), '6', 0);
+	kb_add(x_set_arg,		CTRL('['), '7', 0);
+	kb_add(x_set_arg,		CTRL('['), '8', 0);
+	kb_add(x_set_arg,		CTRL('['), '9', 0);
 
 	/* ctrl arrow keys */
-	kb_add(x_mv_end,		NULL, CTRL('['), '[', '1', ';', '5', 'A', 0); /* ctrl up */
-	kb_add(x_mv_begin,		NULL, CTRL('['), '[', '1', ';', '5', 'B', 0); /* ctrl down */
-	kb_add(x_mv_fword,		NULL, CTRL('['), '[', '1', ';', '5', 'C', 0); /* ctrl right */
-	kb_add(x_mv_bword,		NULL, CTRL('['), '[', '1', ';', '5', 'D', 0); /* ctrl left */
+	kb_add(x_mv_end,		CTRL('['), '[', '1', ';', '5', 'A', 0); /* ctrl up */
+	kb_add(x_mv_begin,		CTRL('['), '[', '1', ';', '5', 'B', 0); /* ctrl down */
+	kb_add(x_mv_fword,		CTRL('['), '[', '1', ';', '5', 'C', 0); /* ctrl right */
+	kb_add(x_mv_bword,		CTRL('['), '[', '1', ';', '5', 'D', 0); /* ctrl left */
 }
 
 void
@@ -1565,17 +1565,17 @@ x_emacs_keys(X_chars *ec)
 {
 	x_bind_quiet = 1;
 	if (ec->erase >= 0) {
-		kb_add(x_del_back, NULL, ec->erase, 0);
-		kb_add(x_del_bword, NULL, CTRL('['), ec->erase, 0);
+		kb_add(x_del_back, ec->erase, 0);
+		kb_add(x_del_bword, CTRL('['), ec->erase, 0);
 	}
 	if (ec->kill >= 0)
-		kb_add(x_del_line, NULL, ec->kill, 0);
+		kb_add(x_del_line, ec->kill, 0);
 	if (ec->werase >= 0)
-		kb_add(x_del_bword, NULL, ec->werase, 0);
+		kb_add(x_del_bword, ec->werase, 0);
 	if (ec->intr >= 0)
-		kb_add(x_abort, NULL, ec->intr, 0);
+		kb_add(x_abort, ec->intr, 0);
 	if (ec->quit >= 0)
-		kb_add(x_noop, NULL, ec->quit, 0);
+		kb_add(x_noop, ec->quit, 0);
 	x_bind_quiet = 0;
 }
 
diff --git a/jobs.c b/jobs.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: jobs.c,v 1.57 2018/01/05 15:44:31 jca Exp $	*/
+/*	$OpenBSD: jobs.c,v 1.58 2018/01/08 22:22:28 benno Exp $	*/
 
 /*
  * Process and job control
@@ -921,7 +921,7 @@ j_async(void)
 
 /* Make j the last async process
  *
- * If jobs are compiled in then this routine expects sigchld to be blocked.
+ * Expects sigchld to be blocked.
  */
 static void
 j_set_async(Job *j)
@@ -957,7 +957,7 @@ j_set_async(Job *j)
 
 /* Start a job: set STARTED, check for held signals and set j->last_proc
  *
- * If jobs are compiled in then this routine expects sigchld to be blocked.
+ * Expects sigchld to be blocked.
  */
 static void
 j_startjob(Job *j)
@@ -979,7 +979,7 @@ j_startjob(Job *j)
 /*
  * wait for job to complete or change state
  *
- * If jobs are compiled in then this routine expects sigchld to be blocked.
+ * Expects sigchld to be blocked.
  */
 static int
 j_waitj(Job *j,
@@ -1103,7 +1103,7 @@ j_waitj(Job *j,
 
 /* SIGCHLD handler to reap children and update job states
  *
- * If jobs are compiled in then this routine expects sigchld to be blocked.
+ * Expects sigchld to be blocked.
  */
 static void
 j_sigchld(int sig)
@@ -1176,7 +1176,7 @@ finished:
  * and state are updated, asynchronous job notification is done and,
  * if unneeded, the job is removed.
  *
- * If jobs are compiled in then this routine expects sigchld to be blocked.
+ * Expects sigchld to be blocked.
  */
 static void
 check_job(Job *j)
@@ -1278,7 +1278,7 @@ check_job(Job *j)
 /*
  * Print job status in either short, medium or long format.
  *
- * If jobs are compiled in then this routine expects sigchld to be blocked.
+ * Expects sigchld to be blocked.
  */
 static void
 j_print(Job *j, int how, struct shf *shf)
@@ -1385,7 +1385,7 @@ j_print(Job *j, int how, struct shf *shf)
 
 /* Convert % sequence to job
  *
- * If jobs are compiled in then this routine expects sigchld to be blocked.
+ * Expects sigchld to be blocked.
  */
 static Job *
 j_lookup(const char *cp, int *ecodep)
@@ -1486,7 +1486,7 @@ static Proc	*free_procs;
 
 /* allocate a new job and fill in the job number.
  *
- * If jobs are compiled in then this routine expects sigchld to be blocked.
+ * Expects sigchld to be blocked.
  */
 static Job *
 new_job(void)
@@ -1514,7 +1514,7 @@ new_job(void)
 
 /* Allocate new process struct
  *
- * If jobs are compiled in then this routine expects sigchld to be blocked.
+ * Expects sigchld to be blocked.
  */
 static Proc *
 new_proc(void)
@@ -1533,7 +1533,7 @@ new_proc(void)
 /* Take job out of job_list and put old structures into free list.
  * Keeps nzombies, last_job and async_job up to date.
  *
- * If jobs are compiled in then this routine expects sigchld to be blocked.
+ * Expects sigchld to be blocked.
  */
 static void
 remove_job(Job *j, const char *where)
@@ -1570,10 +1570,10 @@ remove_job(Job *j, const char *where)
 		async_job = NULL;
 }
 
-/* put j in a particular location (taking it out job_list if it is there
- * already)
+/* Put j in a particular location (taking it out of job_list if it is
+ * there already)
  *
- * If jobs are compiled in then this routine expects sigchld to be blocked.
+ * Expects sigchld to be blocked.
  */
 static void
 put_job(Job *j, int where)
@@ -1608,7 +1608,7 @@ put_job(Job *j, int where)
 
 /* nuke a job (called when unable to start full job).
  *
- * If jobs are compiled in then this routine expects sigchld to be blocked.
+ * Expects sigchld to be blocked.
  */
 static int
 kill_job(Job *j, int sig)