From 643cd0b7e920eb13b788ef38cca6ceed0441309b Mon Sep 17 00:00:00 2001 From: tg Date: Sat, 30 May 2015 22:14:06 +0000 Subject: [PATCH 01/21] add missing initialisation of stack memory to BAFHHostStr(); fix comments for BAFHror() --- mirhash.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/mirhash.h b/mirhash.h index 05729bc..df4a9dc 100644 --- a/mirhash.h +++ b/mirhash.h @@ -1,6 +1,6 @@ /*- - * Copyright © 2011, 2014 - * Thorsten Glaser + * Copyright © 2011, 2014, 2015 + * Thorsten “mirabilos” Glaser * * Provided that these terms and disclaimer and all copyright notices * are retained or reproduced in an accompanying document, permission @@ -44,7 +44,7 @@ #include -__RCSID("$MirOS: src/bin/mksh/mirhash.h,v 1.3 2014/10/02 19:34:06 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/mirhash.h,v 1.4 2015/05/30 22:14:06 tg Exp $"); /*- * BAFH itself is defined by the following primitives: @@ -61,7 +61,8 @@ __RCSID("$MirOS: src/bin/mksh/mirhash.h,v 1.3 2014/10/02 19:34:06 tg Exp $"); * the context is (still) zero, adding a NUL byte is not ignored. * * • BAFHror(eax,cl) evaluates to the unsigned 32-bit integer “eax”, - * rotated right by “cl” ∈ [0;31]; no casting, be careful! + * rotated right by “cl” ∈ [0; 31] (no casting, be careful!) where + * “eax” must be uint32_t and “cl” an in-range integer. * * • BAFHFinish(ctx) avalanches the context around so every sub-byte * depends on all input octets; afterwards, the context variable’s @@ -88,7 +89,7 @@ __RCSID("$MirOS: src/bin/mksh/mirhash.h,v 1.3 2014/10/02 19:34:06 tg Exp $"); * • BAFHHostStr(ctx,buf) does the same for C strings. * * All macros may use ctx multiple times in their expansion, but all - * other arguments are always evaluated at most once. + * other arguments are always evaluated at most once except BAFHror. * * To stay portable, never use the BAFHHost*() macros (these are for * host-local entropy shuffling), and encode numbers using ULEB128. @@ -206,6 +207,7 @@ __RCSID("$MirOS: src/bin/mksh/mirhash.h,v 1.3 2014/10/02 19:34:06 tg Exp $"); } BAFHHost_v; \ \ BAFHUpdate_s = (const void *)(s); \ + BAFHHost_v.as_u32 = 0; \ if ((BAFHHost_v.as_u8[0] = *BAFHUpdate_s) != 0) \ ++BAFHUpdate_s; \ if ((BAFHHost_v.as_u8[1] = *BAFHUpdate_s) != 0) \ From f03037706ce6bcb107a73bb6cfe0e10e74391737 Mon Sep 17 00:00:00 2001 From: tg Date: Sat, 27 Jun 2015 20:44:01 +0000 Subject: [PATCH 02/21] cd does weird things wrt. error messages; slightly better, from carstenh via IRC --- dot.mkshrc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dot.mkshrc b/dot.mkshrc index d24397f..1f9b5fa 100644 --- a/dot.mkshrc +++ b/dot.mkshrc @@ -1,5 +1,5 @@ # $Id$ -# $MirOS: src/bin/mksh/dot.mkshrc,v 1.97 2015/04/29 20:56:18 tg Exp $ +# $MirOS: src/bin/mksh/dot.mkshrc,v 1.98 2015/06/27 20:44:01 tg Exp $ #- # Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013, 2014, 2015 @@ -112,7 +112,7 @@ function chpwd { \: } \chpwd . -function cd { +cd() { \builtin cd "$@" || \return $? \chpwd "$@" } From 0bdc395a81fbf8729b124137b1b9386adb21fa52 Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 28 Jun 2015 14:57:25 +0000 Subject: [PATCH 03/21] =?UTF-8?q?permit=20read=20-N=20n=20(n=20=E2=89=A0?= =?UTF-8?q?=20-1)=20and=20read=20-t=20to=20return=20partial=20reads=20with?= =?UTF-8?q?=20$=3F=20=3D=3D=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit issue spotted by carstenh, could have been a documentation ambiguity issue (as -N was designed to read and return exactly n bytes), but this resolves it in a way both backwards-compatible and user-pleasing --- funcs.c | 10 ++++++---- mksh.1 | 10 +++++++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/funcs.c b/funcs.c index bd0124a..177530a 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.272 2015/05/01 23:16:29 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.273 2015/06/28 14:57:24 tg Exp $"); #if HAVE_KILLPG /* @@ -1964,8 +1964,9 @@ c_read(const char **wp) break; case 0: /* timeout expired for this call */ - rv = 1; - goto c_read_out; + bytesread = 0; + /* fake EOF read; all cases return 1 */ + goto c_read_didread; default: bi_errorf("%s: %s", Tselect, cstrerror(errno)); rv = 2; @@ -1990,6 +1991,7 @@ c_read(const char **wp) goto c_read_readloop; } + c_read_didread: switch (readmode) { case READALL: if (bytesread == 0) { @@ -2012,7 +2014,7 @@ c_read(const char **wp) if (bytesread == 0) { /* end of file reached */ rv = 1; - xp = Xstring(xs, xp); + /* may be partial read: $? = 1, but content */ goto c_read_readdone; } xp += bytesread; diff --git a/mksh.1 b/mksh.1 index 6f2c257..adcc969 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.367 2015/05/23 17:43:20 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.368 2015/06/28 14:57:25 tg Exp $ .\" $OpenBSD: ksh.1,v 1.159 2015/03/25 12:10:52 jca Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -74,7 +74,7 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: May 23 2015 $ +.Dd $Mdocdate: June 28 2015 $ .\" .\" Check which macro package we use, and do other -mdoc setup. .\" @@ -3832,7 +3832,8 @@ if empty, instead of the ASCII newline character as input line delimiter. .It Fl N Ar z Instead of reading till end-of-line, read exactly .Ar z -bytes; less if EOF or a timeout occurs. +bytes. +If EOF or a timeout occurs, a partial read is returned with exit status 1. .It Fl n Ar z Instead of reading till end-of-line, read up to .Ar z @@ -3851,6 +3852,9 @@ The argument must immediately follow the option character. Interrupt reading after .Ar n seconds (specified as positive decimal value with an optional fractional part). +The exit status of +.Nm read +is 1 if the timeout occurred, but partial reads may still be returned. .It Fl r Normally, the ASCII backslash character escapes the special meaning of the following character and is stripped from the input; From 7a1acedd4a482ffb145c3e6143c41f29d83d5f36 Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 28 Jun 2015 16:23:24 +0000 Subject: [PATCH 04/21] bump; nothing to merge from oksh, and nothing more from me today --- check.t | 6 +++--- sh.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/check.t b/check.t index 48a92d9..dbae911 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.694 2015/05/23 17:43:18 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.695 2015/06/28 16:23:22 tg Exp $ # -*- mode: sh -*- #- # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, @@ -30,7 +30,7 @@ # (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date expected-stdout: - @(#)MIRBSD KSH R51 2015/05/23 + @(#)MIRBSD KSH R51 2015/06/28 description: Check version of shell. stdin: @@ -39,7 +39,7 @@ name: KSH_VERSION category: shell:legacy-no --- expected-stdout: - @(#)LEGACY KSH R51 2015/05/23 + @(#)LEGACY KSH R51 2015/06/28 description: Check version of legacy shell. stdin: diff --git a/sh.h b/sh.h index d5de277..131dea6 100644 --- a/sh.h +++ b/sh.h @@ -169,9 +169,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.730 2015/05/23 17:43:22 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.731 2015/06/28 16:23:24 tg Exp $"); #endif -#define MKSH_VERSION "R51 2015/05/23" +#define MKSH_VERSION "R51 2015/06/28" /* arithmetic types: C implementation */ #if !HAVE_CAN_INTTYPES From 11a2f9d822a278034e594bd9dc2582abaed15c5b Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 5 Jul 2015 13:49:42 +0000 Subject: [PATCH 05/21] make $LINENO in PS1 equivalent to ! (bug spotted by carstenh in IRC) --- lex.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lex.c b/lex.c index 3046e52..137e39f 100644 --- a/lex.c +++ b/lex.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.201 2015/04/29 20:07:33 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.202 2015/07/05 13:49:42 tg Exp $"); /* * states while lexing word @@ -1495,6 +1495,7 @@ set_prompt(int to, Source *s) struct shf *shf; char * volatile ps1; Area *saved_atemp; + int saved_lineno; ps1 = str_val(global("PS1")); shf = shf_sopen(NULL, strlen(ps1) * 2, @@ -1506,6 +1507,9 @@ set_prompt(int to, Source *s) shf_fprintf(shf, "%lu", s ? (unsigned long)s->line + 1 : 0UL); ps1 = shf_sclose(shf); + saved_lineno = current_lineno; + if (s) + current_lineno = s->line + 1; saved_atemp = ATEMP; newenv(E_ERRH); if (kshsetjmp(e->jbuf)) { @@ -1521,6 +1525,7 @@ set_prompt(int to, Source *s) char *cp = substitute(ps1, 0); strdupx(prompt, cp, saved_atemp); } + current_lineno = saved_lineno; quitenv(NULL); } break; From bbf0558f6a26f2a7361d2f11fa15cbb07fe0fdfa Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 5 Jul 2015 14:33:21 +0000 Subject: [PATCH 06/21] in print_columns, skip space padding for all last cells, not just those in the last column, for jagged arrays --- misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc.c b/misc.c index 82f57ee..fca40d6 100644 --- a/misc.c +++ b/misc.c @@ -30,7 +30,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.232 2015/05/01 23:16:30 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.233 2015/07/05 14:33:21 tg Exp $"); #define KSH_CHVT_FLAG #ifdef MKSH_SMALL @@ -1286,7 +1286,7 @@ print_columns(struct shf *shf, unsigned int n, if (i < n) { shf_fprintf(shf, "%*s", max_col, (*func)(str, max_oct, i, arg)); - if (c + 1 < cols) + if (i + rows < n) shf_fprintf(shf, "%*s", nspace, null); } } From 62e27c3e07e7685c535a299c639a6b889437dac5 Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 5 Jul 2015 14:43:08 +0000 Subject: [PATCH 07/21] simplify print_columns func argument: no need to return the first arg any more --- exec.c | 12 +++++------- funcs.c | 7 +++---- misc.c | 21 +++++++++++---------- sh.h | 4 ++-- 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/exec.c b/exec.c index affc23b..e01aacc 100644 --- a/exec.c +++ b/exec.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.152 2015/04/29 18:32:43 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.153 2015/07/05 14:43:05 tg Exp $"); #ifndef MKSH_DEFAULT_EXECSHELL #define MKSH_DEFAULT_EXECSHELL "/bin/sh" @@ -41,8 +41,8 @@ static const char *dbteste_getopnd(Test_env *, Test_op, bool); static void dbteste_error(Test_env *, int, const char *); static int search_access(const char *, int); /* XXX: horrible kludge to fit within the framework */ -static char *plain_fmt_entry(char *, size_t, unsigned int, const void *); -static char *select_fmt_entry(char *, size_t, unsigned int, const void *); +static void plain_fmt_entry(char *, size_t, unsigned int, const void *); +static void select_fmt_entry(char *, size_t, unsigned int, const void *); /* * execute command tree @@ -1610,7 +1610,7 @@ struct select_menu_info { }; /* format a single select menu item */ -static char * +static void select_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg) { const struct select_menu_info *smi = @@ -1618,7 +1618,6 @@ select_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg) shf_snprintf(buf, buflen, "%*u) %s", smi->num_width, i + 1, smi->args[i]); - return (buf); } /* @@ -1664,11 +1663,10 @@ pr_menu(const char * const *ap) true); } -static char * +static void plain_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg) { strlcpy(buf, ((const char * const *)arg)[i], buflen); - return (buf); } void diff --git a/funcs.c b/funcs.c index 177530a..573e9f6 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.273 2015/06/28 14:57:24 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.274 2015/07/05 14:43:06 tg Exp $"); #if HAVE_KILLPG /* @@ -224,7 +224,7 @@ static int test_primary(Test_env *, bool); static Test_op ptest_isa(Test_env *, Test_meta); static const char *ptest_getopnd(Test_env *, Test_op, bool); static void ptest_error(Test_env *, int, const char *); -static char *kill_fmt_entry(char *, size_t, unsigned int, const void *); +static void kill_fmt_entry(char *, size_t, unsigned int, const void *); static void p_time(struct shf *, bool, long, int, int, const char *, const char *); @@ -1307,7 +1307,7 @@ c_fgbg(const char **wp) #endif /* format a single kill item */ -static char * +static void kill_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg) { const struct kill_info *ki = (const struct kill_info *)arg; @@ -1317,7 +1317,6 @@ kill_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg) ki->num_width, i, ki->name_width, sigtraps[i].name, sigtraps[i].mess); - return (buf); } int diff --git a/misc.c b/misc.c index fca40d6..0a3227b 100644 --- a/misc.c +++ b/misc.c @@ -30,7 +30,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.233 2015/07/05 14:33:21 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.234 2015/07/05 14:43:07 tg Exp $"); #define KSH_CHVT_FLAG #ifdef MKSH_SMALL @@ -173,11 +173,11 @@ struct options_info { int opts[NELEM(options)]; }; -static char *options_fmt_entry(char *, size_t, unsigned int, const void *); +static void options_fmt_entry(char *, size_t, unsigned int, const void *); static void printoptions(bool); /* format a single select menu item */ -static char * +static void options_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg) { const struct options_info *oi = (const struct options_info *)arg; @@ -185,7 +185,6 @@ options_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg) shf_snprintf(buf, buflen, "%-*s %s", oi->opt_width, OFN(oi->opts[i]), Flag(oi->opts[i]) ? "on" : "off"); - return (buf); } static void @@ -1227,7 +1226,7 @@ print_value_quoted(struct shf *shf, const char *s) */ void print_columns(struct shf *shf, unsigned int n, - char *(*func)(char *, size_t, unsigned int, const void *), + void (*func)(char *, size_t, unsigned int, const void *), const void *arg, size_t max_oct, size_t max_colz, bool prefcol) { unsigned int i, r, c, rows, cols, nspace, max_col; @@ -1264,9 +1263,11 @@ print_columns(struct shf *shf, unsigned int n, /* if we can only print one column anyway, skip the goo */ if (cols < 2) { - for (i = 0; i < n; ++i) - shf_fprintf(shf, "%s\n", - (*func)(str, max_oct, i, arg)); + for (i = 0; i < n; ++i) { + (*func)(str, max_oct, i, arg); + shf_puts(str, shf); + shf_putc('\n', shf); + } goto out; } @@ -1284,8 +1285,8 @@ print_columns(struct shf *shf, unsigned int n, for (c = 0; c < cols; c++) { i = c * rows + r; if (i < n) { - shf_fprintf(shf, "%*s", max_col, - (*func)(str, max_oct, i, arg)); + (*func)(str, max_oct, i, arg); + shf_fprintf(shf, "%*s", max_col, str); if (i + rows < n) shf_fprintf(shf, "%*s", nspace, null); } diff --git a/sh.h b/sh.h index 131dea6..5ab4d16 100644 --- a/sh.h +++ b/sh.h @@ -169,7 +169,7 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.731 2015/06/28 16:23:24 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.732 2015/07/05 14:43:08 tg Exp $"); #endif #define MKSH_VERSION "R51 2015/06/28" @@ -1894,7 +1894,7 @@ int ksh_getopt(const char **, Getopt *, const char *); void print_value_quoted(struct shf *, const char *); char *quote_value(const char *); void print_columns(struct shf *, unsigned int, - char *(*)(char *, size_t, unsigned int, const void *), + void (*)(char *, size_t, unsigned int, const void *), const void *, size_t, size_t, bool); void strip_nuls(char *, size_t) MKSH_A_BOUNDED(__string__, 1, 2); From 69eac312de5cdfbc01c364548439b103067d64db Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 5 Jul 2015 14:47:41 +0000 Subject: [PATCH 08/21] omit trailing whitespace for print_columns --- misc.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/misc.c b/misc.c index 0a3227b..6d881ba 100644 --- a/misc.c +++ b/misc.c @@ -30,7 +30,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.234 2015/07/05 14:43:07 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.235 2015/07/05 14:47:41 tg Exp $"); #define KSH_CHVT_FLAG #ifdef MKSH_SMALL @@ -1283,13 +1283,14 @@ print_columns(struct shf *shf, unsigned int n, nspace = 1; for (r = 0; r < rows; r++) { for (c = 0; c < cols; c++) { - i = c * rows + r; - if (i < n) { - (*func)(str, max_oct, i, arg); - shf_fprintf(shf, "%*s", max_col, str); - if (i + rows < n) - shf_fprintf(shf, "%*s", nspace, null); - } + if ((i = c * rows + r) >= n) + break; + (*func)(str, max_oct, i, arg); + if (i + rows >= n) + shf_puts(str, shf); + else + shf_fprintf(shf, "%*s%*s", + max_col, str, nspace, null); } shf_putchar('\n', shf); } From 5eeeaab8cfcd75fa87b3358fe286aa28746b2d28 Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 5 Jul 2015 14:58:33 +0000 Subject: [PATCH 09/21] ensure at least two spaces of cell-to-cell horizontal padding in print_columns; audit all callers of print_columns to always pass the exact maximum sizes --- misc.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/misc.c b/misc.c index 6d881ba..8ad5864 100644 --- a/misc.c +++ b/misc.c @@ -30,7 +30,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.235 2015/07/05 14:47:41 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.236 2015/07/05 14:58:33 tg Exp $"); #define KSH_CHVT_FLAG #ifdef MKSH_SMALL @@ -1255,11 +1255,12 @@ print_columns(struct shf *shf, unsigned int n, str = alloc(max_oct, ATEMP); /* - * We use (max_col + 1) to consider the space separator. - * Note that no space is printed after the last column - * to avoid problems with terminals that have auto-wrap. + * We use (max_col + 2) to consider the separator space. + * Note that no spaces are printed after the last column + * to avoid problems with terminals that have auto-wrap, + * but we need to also take this into account in x_cols. */ - cols = x_cols / (max_col + 1); + cols = (x_cols + 1) / (max_col + 2); /* if we can only print one column anyway, skip the goo */ if (cols < 2) { @@ -1278,9 +1279,9 @@ print_columns(struct shf *shf, unsigned int n, } nspace = (x_cols - max_col * cols) / cols; + if (nspace < 2) + nspace = 2; max_col = -max_col; - if (nspace <= 0) - nspace = 1; for (r = 0; r < rows; r++) { for (c = 0; c < cols; c++) { if ((i = c * rows + r) >= n) From 69ec1002ebfc58d989d68545ba6656f673fbc0f7 Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 5 Jul 2015 15:12:04 +0000 Subject: [PATCH 10/21] add new expected-fail from POSIX --- check.t | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/check.t b/check.t index dbae911..c37d63f 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.695 2015/06/28 16:23:22 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.696 2015/07/05 15:12:04 tg Exp $ # -*- mode: sh -*- #- # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, @@ -8533,6 +8533,7 @@ description: Ensure concatenating behaviour matches other shells stdin: showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; } + #showargs 0 ""$@ x=; showargs 1 "$x"$@ set A; showargs 2 "${@:+}" n() { echo "$#"; } @@ -8567,6 +8568,17 @@ expected-stdout: 0 1 --- +name: varexpand-null-3a +description: + Ensure concatenating behaviour matches other shells + (currently broken cases) +expected-fail: yes +stdin: + showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; } + showargs 0 ""$@ +expected-stdout: + <0> <> . +--- name: print-funny-chars description: Check print builtin's capability to output designated characters From b478d334d9a63700ee46b8ade857dc19c598657d Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 5 Jul 2015 15:22:41 +0000 Subject: [PATCH 11/21] merge spelling stuff from oksh --- mksh.1 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mksh.1 b/mksh.1 index adcc969..9610540 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,5 +1,5 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.368 2015/06/28 14:57:25 tg Exp $ -.\" $OpenBSD: ksh.1,v 1.159 2015/03/25 12:10:52 jca Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.369 2015/07/05 15:22:41 tg Exp $ +.\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, .\" 2010, 2011, 2012, 2013, 2014, 2015 @@ -74,7 +74,7 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: June 28 2015 $ +.Dd $Mdocdate: July 5 2015 $ .\" .\" Check which macro package we use, and do other -mdoc setup. .\" @@ -476,7 +476,7 @@ and .Ql } delimit .Xr csh 1 Ns -style -alterations (see +alternations (see .Sx Brace expansion below); and finally, @@ -2145,7 +2145,7 @@ The .Ic alias Fl d command may be used to list, change, and add to this cache (e.g.\& .Ic alias \-d fac=/usr/local/facilities; cd \*(TIfac/bin ) . -.Ss Brace expansion (alteration) +.Ss Brace expansion (alternation) Brace expressions take the following form: .Bd -unfilled -offset indent .Sm off From b9a8fdf9059beef60a0daa2e6bd2a4208d27c2b7 Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 5 Jul 2015 15:45:18 +0000 Subject: [PATCH 12/21] implement cat thing for realpath and rename too: if flag, call external --- Build.sh | 4 +++- exec.c | 25 +++++++++++++++---------- mksh.1 | 13 ++++++++++++- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Build.sh b/Build.sh index b0510f5..d75b15e 100644 --- a/Build.sh +++ b/Build.sh @@ -1,5 +1,5 @@ #!/bin/sh -srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.679 2015/05/01 16:08:26 tg Exp $' +srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.680 2015/07/05 15:45:16 tg Exp $' #- # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013, 2014, 2015 @@ -2646,6 +2646,8 @@ MKSH_NOPWNAM skip PAM calls, for -static on glibc or Solaris MKSH_NO_CMDLINE_EDITING disable command line editing code entirely MKSH_NO_DEPRECATED_WARNING omit warning when deprecated stuff is run MKSH_NO_EXTERNAL_CAT omit hack to skip cat builtin when flags passed +MKSH_NO_EXTERNAL_REALPATH same for realpath builtin +MKSH_NO_EXTERNAL_RENAME same for rename builtin MKSH_NO_LIMITS omit ulimit code MKSH_NO_SIGSETJMP define if sigsetjmp is broken or not available MKSH_NO_SIGSUSPEND use sigprocmask+pause instead of sigsuspend diff --git a/exec.c b/exec.c index e01aacc..3f8863c 100644 --- a/exec.c +++ b/exec.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.153 2015/07/05 14:43:05 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.154 2015/07/05 15:45:17 tg Exp $"); #ifndef MKSH_DEFAULT_EXECSHELL #define MKSH_DEFAULT_EXECSHELL "/bin/sh" @@ -607,16 +607,21 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap, subst_exstat = 0; break; } +#if !defined(MKSH_NO_EXTERNAL_CAT) || \ + !defined(MKSH_NO_EXTERNAL_REALPATH) || \ + !defined(MKSH_NO_EXTERNAL_RENAME) + } else if ( #ifndef MKSH_NO_EXTERNAL_CAT - } else if (tp->val.f == c_cat) { - /* - * if we have any flags, do not use the builtin - * in theory, we could allow -u, but that would - * mean to use ksh_getopt here and possibly ad- - * ded complexity and more code and isn't worth - * additional hassle (and the builtin must call - * ksh_getopt already but can't come back here) - */ + tp->val.f == c_cat || +#endif +#ifndef MKSH_NO_EXTERNAL_REALPATH + tp->val.f == c_realpath || +#endif +#ifndef MKSH_NO_EXTERNAL_RENAME + tp->val.f == c_rename || +#endif + 0) { + /* if we have any flags, do not use the builtin */ if (ap[1] && ap[1][0] == '-' && ap[1][1] != '\0' && /* argument, begins with -, is not - or -- */ (ap[1][1] != '-' || ap[1][2] != '\0')) diff --git a/mksh.1 b/mksh.1 index 9610540..9efdc1e 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.369 2015/07/05 15:22:41 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.370 2015/07/05 15:45:18 tg Exp $ .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -3957,6 +3957,12 @@ it's also checked for existence and whether it is a directory; otherwise, returns 0 if the pathname either exists or can be created immediately, i.e. all but the last component exist and are directories. .Pp +Unless compiled with +.Dv MKSH_NO_EXTERNAL_REALPATH , +if any options are given and this is not a direct builtin call, an external +.Xr realpath 1 +utility is invoked instead. +.Pp .It Xo .Ic rename .Op Fl \- @@ -3971,6 +3977,11 @@ This builtin is intended for emergency situations where .Pa /bin/mv becomes unusable, and directly calls .Xr rename 2 . +Unless compiled with +.Dv MKSH_NO_EXTERNAL_RENAME , +if any options are given and this is not a direct builtin call, an external +.Xr rename 1 +utility is invoked instead. .Pp .It Ic return Op Ar status Returns from a function or From b87215bbaf5763a4e368c6b8025b103b5e266ad0 Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 5 Jul 2015 16:47:28 +0000 Subject: [PATCH 13/21] =?UTF-8?q?when=20storing=20commands=20with=20embedd?= =?UTF-8?q?ed=20newlines,=20don=E2=80=99t=20take=20those=20as=20end=20of?= =?UTF-8?q?=20string=20(inspired=20fix=20from=20Debian=20#783978;=20bug=20?= =?UTF-8?q?in=20original=20pdksh=20COMPLEX=5FHISTORY=20code)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- histrap.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/histrap.c b/histrap.c index 37ee258..4bd9066 100644 --- a/histrap.c +++ b/histrap.c @@ -27,7 +27,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.143 2015/04/29 20:44:35 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.144 2015/07/05 16:47:28 tg Exp $"); Trap sigtraps[ksh_NSIG + 1]; static struct sigaction Sigact_ign; @@ -634,11 +634,13 @@ void histsave(int *lnp, const char *cmd, bool dowrite MKSH_A_UNUSED, bool ignoredups) { char **hp; - char *c, *cp; + char *c; + const char *ccp; - strdupx(c, cmd, APERM); - if ((cp = strchr(c, '\n')) != NULL) - *cp = '\0'; + ccp = cmd + strlen(cmd); + while (ccp > cmd && ccp[-1] == '\n') + --ccp; + strndupx(c, cmd, ccp - cmd, APERM); if (ignoredups && !strcmp(c, *histptr) #if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY From 757d8573190ae9f457fecaf3dc92919430c78cad Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 5 Jul 2015 16:48:28 +0000 Subject: [PATCH 14/21] greatly simplify hist_execute (useless to cut a string in twain, then restore the very same string), except now, the one trailing newline is not removed (except in histsave) --- histrap.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/histrap.c b/histrap.c index 4bd9066..fdad711 100644 --- a/histrap.c +++ b/histrap.c @@ -27,7 +27,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.144 2015/07/05 16:47:28 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.145 2015/07/05 16:48:28 tg Exp $"); Trap sigtraps[ksh_NSIG + 1]; static struct sigaction Sigact_ign; @@ -371,7 +371,6 @@ hist_execute(char *cmd) static int last_line = -1; Source *sold; int ret; - char *p, *q; /* Back up over last histsave */ if (histptr >= history && last_line != hist_source->line) { @@ -381,22 +380,7 @@ hist_execute(char *cmd) last_line = hist_source->line; } - for (p = cmd; p; p = q) { - if ((q = strchr(p, '\n'))) { - /* kill the newline */ - *q++ = '\0'; - if (!*q) - /* ignore trailing newline */ - q = NULL; - } - histsave(&hist_source->line, p, true, true); - - /* POSIX doesn't say this is done... */ - shellf("%s\n", p); - if (q) - /* restore \n (trailing \n not restored) */ - q[-1] = '\n'; - } + histsave(&hist_source->line, cmd, true, true); /*- * Commands are executed here instead of pushing them onto the From 0d5b514e636357073904dc8262a9bb772718ac2b Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 5 Jul 2015 17:04:26 +0000 Subject: [PATCH 15/21] =?UTF-8?q?now=20removes=20*all*=20trailing=20newlin?= =?UTF-8?q?es=20(by=20reusing=20histsave=20result,=20saves=20code),=20plus?= =?UTF-8?q?=20plugs=20an=20ancient=20memory=20leak=20(hist=5Fexecute=20afr?= =?UTF-8?q?ee=E2=80=99s=20its=20arg=20now);=20also=20partial=20revert=20of?= =?UTF-8?q?=20commitid=2078014291f06497b3=20as=20COMPLEX=5FHISTORY=20handl?= =?UTF-8?q?es=20multi-line=20commands=20correctly=20now=20(r1.4,=202005-05?= =?UTF-8?q?-23)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- check.t | 6 +++--- histrap.c | 17 +++++++++++------ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/check.t b/check.t index c37d63f..53f1ba1 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.696 2015/07/05 15:12:04 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.697 2015/07/05 17:04:24 tg Exp $ # -*- mode: sh -*- #- # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, @@ -3582,7 +3582,7 @@ expected-stdout: a new line 1 echo abc def 2 echo FOOBAR def - 3 echo a new line + echo a new line expected-stderr-pattern: /^X*echo FOOBAR def\necho a new line\nX*$/ --- @@ -3664,7 +3664,7 @@ expected-stdout: a new line 1 echo abc def 2 echo FOOBAR def - 3 echo a new line + echo a new line expected-stderr-pattern: /^X*13\n32\necho FOOBAR def\necho a new line\nX*$/ --- diff --git a/histrap.c b/histrap.c index fdad711..4e3136d 100644 --- a/histrap.c +++ b/histrap.c @@ -27,7 +27,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.145 2015/07/05 16:48:28 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.146 2015/07/05 17:04:26 tg Exp $"); Trap sigtraps[ksh_NSIG + 1]; static struct sigaction Sigact_ign; @@ -38,7 +38,7 @@ static int writehistline(int, int, const char *); static void writehistfile(int, const char *); #endif -static int hist_execute(char *); +static int hist_execute(char *, Area *); static char **hist_get(const char *, bool, bool); static char **hist_get_oldest(void); @@ -223,7 +223,7 @@ c_fc(const char **wp) xp += len; line = Xclose(xs, xp); } - return (hist_execute(line)); + return (hist_execute(line, ATEMP)); } if (editor && (lflag || nflag)) { @@ -360,13 +360,13 @@ c_fc(const char **wp) shf_close(shf); *xp = '\0'; strip_nuls(Xstring(xs, xp), Xlength(xs, xp)); - return (hist_execute(Xstring(xs, xp))); + return (hist_execute(Xstring(xs, xp), hist_source->areap)); } } -/* Save cmd in history, execute cmd (cmd gets trashed) */ +/* save cmd in history, execute cmd (cmd gets afree’d) */ static int -hist_execute(char *cmd) +hist_execute(char *cmd, Area *areap) { static int last_line = -1; Source *sold; @@ -381,6 +381,11 @@ hist_execute(char *cmd) } histsave(&hist_source->line, cmd, true, true); + /* now *histptr == cmd without all trailing newlines */ + afree(cmd, areap); + cmd = *histptr; + /* pdksh says POSIX doesn’t say this is done, testsuite needs it */ + shellf("%s\n", cmd); /*- * Commands are executed here instead of pushing them onto the From 48af854117ddceeff7711d22b98a69c5de781e18 Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 5 Jul 2015 17:50:40 +0000 Subject: [PATCH 16/21] fix 'command -v' for "shell reserved words" From: Martijn Dekker also adjust manpage accordingly --- funcs.c | 4 ++-- mksh.1 | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/funcs.c b/funcs.c index 573e9f6..b2b04fb 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.274 2015/07/05 14:43:06 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.275 2015/07/05 17:50:39 tg Exp $"); #if HAVE_KILLPG /* @@ -538,7 +538,7 @@ c_whence(const char **wp) uint32_t h = 0; tp = NULL; - if ((iam_whence || vflag) && !pflag) + if (!pflag) tp = ktsearch(&keywords, id, h = hash(id)); if (!tp && !pflag) { tp = ktsearch(&aliases, id, h ? h : hash(id)); diff --git a/mksh.1 b/mksh.1 index 9efdc1e..268b463 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.370 2015/07/05 15:45:18 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.371 2015/07/05 17:50:40 tg Exp $ .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -3296,9 +3296,9 @@ option is given, instead of executing .Ar cmd , information about what would be executed is given (and the same is done for .Ar arg ... ) . -For special and regular built-in commands and functions, their names are simply -printed; for aliases, a command that defines them is printed; and for commands -found by searching the +For builtins, functions and keywords, their names are simply printed; +for aliases, a command that defines them is printed; +for utilities found by searching the .Ev PATH parameter, the full path of the command is printed. If no command is found From be8c2fa8c27a29997d5767a64fc8e363dc75436d Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 5 Jul 2015 19:02:16 +0000 Subject: [PATCH 17/21] optimise by making use of commitid 1005529AD8D33CF99B9 --- dot.mkshrc | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/dot.mkshrc b/dot.mkshrc index 1f9b5fa..9df3205 100644 --- a/dot.mkshrc +++ b/dot.mkshrc @@ -1,5 +1,5 @@ # $Id$ -# $MirOS: src/bin/mksh/dot.mkshrc,v 1.98 2015/06/27 20:44:01 tg Exp $ +# $MirOS: src/bin/mksh/dot.mkshrc,v 1.99 2015/07/05 19:02:16 tg Exp $ #- # Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013, 2014, 2015 @@ -67,8 +67,9 @@ else \typeset -Uui16 -Z11 pos=0 \typeset -Uui16 -Z5 hv=2147483647 \typeset dasc line i + \set +U - \cat "$@" | { \set +U; if \read -arN -1 line; then + \cat "$@" | if \read -arN -1 line; then \typeset -i1 'line[*]' i=0 while (( i < ${#line[*]} )); do @@ -95,7 +96,7 @@ else \builtin print -n -- '- ' done (( hv == 2147483647 )) || \builtin print -r -- "$dasc|" - fi; } + fi } fi @@ -271,8 +272,8 @@ function smores { # base64 encoder and decoder, RFC compliant, NUL safe, not EBCDIC safe function Lb64decode { - [[ -o utf8-mode ]]; \typeset u=$? c s="$*" t \set +U + \typeset c s="$*" t [[ -n $s ]] || { s=$(\cat; \builtin print x); s=${s%x}; } \typeset -i i=0 j=0 n=${#s} p=0 v x \typeset -i16 o @@ -303,14 +304,13 @@ function Lb64decode { t= done \builtin print -n $t - (( u )) || \set -U } \set -A Lb64encode_tbl -- A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \ a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 + / function Lb64encode { - [[ -o utf8-mode ]]; \typeset u=$? c s t \set +U + \typeset c s t if (( $# )); then \read -raN-1 s <<<"$*" \unset s[${#s[*]}-1] @@ -339,7 +339,6 @@ function Lb64encode { t= fi done - (( u )) || \set -U } # Better Avalanche for the Jenkins Hash @@ -348,8 +347,8 @@ function Lbafh_init { Lbafh_v=0 } function Lbafh_add { - [[ -o utf8-mode ]]; \typeset u=$? s \set +U + \typeset s if (( $# )); then \read -raN-1 s <<<"$*" \unset s[${#s[*]}-1] @@ -362,8 +361,6 @@ function Lbafh_add { ((# Lbafh_v = (Lbafh_v + s[i++] + 1) * 1025 )) ((# Lbafh_v ^= Lbafh_v >> 6 )) done - - (( u )) || \set -U } function Lbafh_finish { \typeset -Ui t @@ -378,10 +375,11 @@ function Lbafh_finish { # strip comments (and leading/trailing whitespace if IFS is set) from # any file(s) given as argument, or stdin if none, and spew to stdout function Lstripcom { - \cat "$@" | { \set -o noglob; while \read _line; do + \set -o noglob + \cat "$@" | while \read _line; do _line=${_line%%#*} [[ -n $_line ]] && \builtin print -r -- $_line - done; } + done } # give MidnightBSD's laffer1 a bit of csh feeling From e0196f47d5be50fb4510b13019ff02ded4fc6424 Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 5 Jul 2015 19:37:18 +0000 Subject: [PATCH 18/21] implement completely new multiline code by delaying history store this commit is valgrind-tested --- check.t | 6 ++--- edit.c | 8 +++---- funcs.c | 6 ++--- histrap.c | 66 ++++++++++++++++++++++++++++++++++++++++++------------- lex.c | 13 +++++++---- main.c | 4 +++- mksh.1 | 5 +++-- sh.h | 13 ++++++++--- 8 files changed, 86 insertions(+), 35 deletions(-) diff --git a/check.t b/check.t index 53f1ba1..34aa403 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.697 2015/07/05 17:04:24 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.698 2015/07/05 19:37:11 tg Exp $ # -*- mode: sh -*- #- # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, @@ -30,7 +30,7 @@ # (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date expected-stdout: - @(#)MIRBSD KSH R51 2015/06/28 + @(#)MIRBSD KSH R51 2015/07/05 description: Check version of shell. stdin: @@ -39,7 +39,7 @@ name: KSH_VERSION category: shell:legacy-no --- expected-stdout: - @(#)LEGACY KSH R51 2015/06/28 + @(#)LEGACY KSH R51 2015/07/05 description: Check version of legacy shell. stdin: diff --git a/edit.c b/edit.c index bc8cc2c..ad29d93 100644 --- a/edit.c +++ b/edit.c @@ -28,7 +28,7 @@ #ifndef MKSH_NO_CMDLINE_EDITING -__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.286 2015/05/03 11:28:53 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.287 2015/07/05 19:37:13 tg Exp $"); /* * in later versions we might use libtermcap for this, but since external @@ -3054,7 +3054,7 @@ x_edit_line(int c MKSH_A_UNUSED) } if (modified) { *xep = '\0'; - histsave(&source->line, xbuf, true, true); + histsave(&source->line, xbuf, HIST_STORE, true); x_arg = 0; } else x_arg = source->line - (histptr - x_histp); @@ -4311,8 +4311,8 @@ vi_cmd(int argcnt, const char *cmd) return (-1); if (modified) { es->cbuf[es->linelen] = '\0'; - histsave(&source->line, es->cbuf, true, - true); + histsave(&source->line, es->cbuf, + HIST_STORE, true); } else argcnt = source->line + 1 - (hlast - hnum); diff --git a/funcs.c b/funcs.c index b2b04fb..64c7d2f 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.275 2015/07/05 17:50:39 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.276 2015/07/05 19:37:14 tg Exp $"); #if HAVE_KILLPG /* @@ -442,7 +442,7 @@ c_print(const char **wp) if (flags & PO_HIST) { Xput(xs, xp, '\0'); - histsave(&source->line, Xstring(xs, xp), true, false); + histsave(&source->line, Xstring(xs, xp), HIST_STORE, false); Xfree(xs, xp); } else { int len = Xlength(xs, xp); @@ -2076,7 +2076,7 @@ c_read(const char **wp) } if (savehist) - histsave(&source->line, Xstring(xs, xp), true, false); + histsave(&source->line, Xstring(xs, xp), HIST_STORE, false); ccp = cp = Xclose(xs, xp); expanding = false; diff --git a/histrap.c b/histrap.c index 4e3136d..320ce77 100644 --- a/histrap.c +++ b/histrap.c @@ -27,7 +27,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.146 2015/07/05 17:04:26 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.147 2015/07/05 19:37:15 tg Exp $"); Trap sigtraps[ksh_NSIG + 1]; static struct sigaction Sigact_ign; @@ -380,7 +380,7 @@ hist_execute(char *cmd, Area *areap) last_line = hist_source->line; } - histsave(&hist_source->line, cmd, true, true); + histsave(&hist_source->line, cmd, HIST_STORE, true); /* now *histptr == cmd without all trailing newlines */ afree(cmd, areap); cmd = *histptr; @@ -620,31 +620,67 @@ histsync(void) * save command in history */ void -histsave(int *lnp, const char *cmd, bool dowrite MKSH_A_UNUSED, bool ignoredups) +histsave(int *lnp, const char *cmd, int svmode, bool ignoredups) { - char **hp; - char *c; + static char *enqueued = NULL; + char **hp, *c; const char *ccp; + if (svmode == HIST_APPEND) { + if (!enqueued) + svmode = HIST_STORE; + } else if (enqueued) { + c = enqueued; + enqueued = NULL; + --*lnp; + histsave(lnp, c, HIST_STORE, true); + afree(c, APERM); + } + + if (svmode == HIST_FLUSH) + return; + ccp = cmd + strlen(cmd); while (ccp > cmd && ccp[-1] == '\n') --ccp; strndupx(c, cmd, ccp - cmd, APERM); - if (ignoredups && !strcmp(c, *histptr) + if (svmode != HIST_APPEND) { + if (ignoredups && !strcmp(c, *histptr) #if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY - && !histsync() + && !histsync() #endif - ) { + ) { + afree(c, APERM); + return; + } + ++*lnp; + } + +#if HAVE_PERSISTENT_HISTORY + if (svmode == HIST_STORE && histfd != -1) + writehistfile(*lnp, c); +#endif + + if (svmode == HIST_QUEUE || svmode == HIST_APPEND) { + size_t nenq, ncmd; + + if (!enqueued) { + if (*c) + enqueued = c; + else + afree(c, APERM); + return; + } + + nenq = strlen(enqueued); + ncmd = strlen(c); + enqueued = aresize(enqueued, nenq + 1 + ncmd + 1, APERM); + enqueued[nenq] = '\n'; + memcpy(enqueued + nenq + 1, c, ncmd + 1); afree(c, APERM); return; } - ++*lnp; - -#if HAVE_PERSISTENT_HISTORY - if (dowrite && histfd != -1) - writehistfile(*lnp, c); -#endif hp = histptr; @@ -855,7 +891,7 @@ histload(Source *s, unsigned char *base, size_t bytes) } } else { s->line = lno--; - histsave(&lno, (char *)(base + 4), false, false); + histsave(&lno, (char *)(base + 4), HIST_NOTE, false); } /* advance base pointer past NUL */ bytes -= ++cp - base; diff --git a/lex.c b/lex.c index 137e39f..7839d90 100644 --- a/lex.c +++ b/lex.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.202 2015/07/05 13:49:42 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.203 2015/07/05 19:37:16 tg Exp $"); /* * states while lexing word @@ -1461,11 +1461,16 @@ getsc_line(Source *s) if (s->type == SFILE) shf_fdclose(s->u.shf); s->str = NULL; - } else if (interactive && *s->str && - (cur_prompt != PS1 || !ctype(*s->str, C_IFS | C_IFSWS))) { - histsave(&s->line, s->str, true, true); + } else if (interactive && *s->str) { + if (cur_prompt != PS1) + histsave(&s->line, s->str, HIST_APPEND, true); + else if (!ctype(*s->str, C_IFS | C_IFSWS)) + histsave(&s->line, s->str, HIST_QUEUE, true); #if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY + else + goto check_for_sole_return; } else if (interactive && cur_prompt == PS1) { + check_for_sole_return: cp = Xstring(s->xs, xp); while (*cp && ctype(*cp, C_IFSWS)) ++cp; diff --git a/main.c b/main.c index 8bb4f0d..eecea60 100644 --- a/main.c +++ b/main.c @@ -34,7 +34,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.293 2015/04/29 20:07:33 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.294 2015/07/05 19:37:16 tg Exp $"); extern char **environ; @@ -803,6 +803,8 @@ shell(Source * volatile s, volatile bool toplevel) set_prompt(PS1, s); } t = compile(s, sfirst); + if (interactive) + histsave(&s->line, NULL, HIST_FLUSH, true); sfirst = false; if (!t) goto source_no_tree; diff --git a/mksh.1 b/mksh.1 index 268b463..fb9666b 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.371 2015/07/05 17:50:40 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.372 2015/07/05 19:37:17 tg Exp $ .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -1859,7 +1859,8 @@ below for more information. .It Ev HISTFILE The name of the file used to store command history. When assigned to or unset, the file is opened, history is truncated -then loaded from the file; subsequent new lines are appended. +then loaded from the file; subsequent new commands (possibly consisting +of several lines) are appended once they successfully compiled. Also, several invocations of the shell will share history if their .Ev HISTFILE parameters all point to the same file. diff --git a/sh.h b/sh.h index 5ab4d16..74d4b57 100644 --- a/sh.h +++ b/sh.h @@ -169,9 +169,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.732 2015/07/05 14:43:08 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.733 2015/07/05 19:37:18 tg Exp $"); #endif -#define MKSH_VERSION "R51 2015/06/28" +#define MKSH_VERSION "R51 2015/07/05" /* arithmetic types: C implementation */ #if !HAVE_CAN_INTTYPES @@ -1625,6 +1625,13 @@ EXTERN char **history; /* saved commands */ EXTERN char **histptr; /* last history item */ EXTERN mksh_ari_t histsize; /* history size */ +/* flags to histsave */ +#define HIST_FLUSH 0 +#define HIST_QUEUE 1 +#define HIST_APPEND 2 +#define HIST_STORE 3 +#define HIST_NOTE 4 + /* user and system time of last j_waitjed job */ EXTERN struct timeval j_usrtime, j_systime; @@ -1751,7 +1758,7 @@ void hist_init(Source *); #if HAVE_PERSISTENT_HISTORY void hist_finish(void); #endif -void histsave(int *, const char *, bool, bool); +void histsave(int *, const char *, int, bool); #if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY bool histsync(void); #endif From 2e4cd728991064733c1d228a64b8544056fa4b30 Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 5 Jul 2015 19:53:46 +0000 Subject: [PATCH 19/21] make certain actions flush the history buffer --- histrap.c | 16 +++++++++++++++- lex.c | 6 ++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/histrap.c b/histrap.c index 320ce77..d19dbb6 100644 --- a/histrap.c +++ b/histrap.c @@ -27,7 +27,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.147 2015/07/05 19:37:15 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.148 2015/07/05 19:53:45 tg Exp $"); Trap sigtraps[ksh_NSIG + 1]; static struct sigaction Sigact_ign; @@ -84,6 +84,9 @@ static const char TFCEDIT_dollaru[] = "${FCEDIT:-/bin/ed} $_"; /* maximum considered size of persistent history file */ #define MKSH_MAXHISTFSIZE ((off_t)1048576 * 96) +/* hidden option */ +#define HIST_DISCARD 5 + int c_fc(const char **wp) { @@ -567,6 +570,7 @@ sethistfile(const char *name) afree(hname, APERM); hname = NULL; /* let's reset the history */ + histsave(NULL, NULL, HIST_DISCARD, true); histptr = history - 1; hist_source->line = 0; } @@ -601,6 +605,8 @@ histsync(void) { bool changed = false; + /* called by histsave(), may not HIST_DISCARD, caller should flush */ + if (histfd != -1) { int lno = hist_source->line; @@ -626,6 +632,12 @@ histsave(int *lnp, const char *cmd, int svmode, bool ignoredups) char **hp, *c; const char *ccp; + if (svmode == HIST_DISCARD) { + afree(enqueued, APERM); + enqueued = NULL; + return; + } + if (svmode == HIST_APPEND) { if (!enqueued) svmode = HIST_STORE; @@ -734,6 +746,8 @@ hist_init(Source *s) enum { hist_init_first, hist_init_retry, hist_init_restore } hs; #endif + histsave(NULL, NULL, HIST_DISCARD, true); + if (Flag(FTALKING) == 0) return; diff --git a/lex.c b/lex.c index 7839d90..fb80244 100644 --- a/lex.c +++ b/lex.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.203 2015/07/05 19:37:16 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.204 2015/07/05 19:53:46 tg Exp $"); /* * states while lexing word @@ -1474,8 +1474,10 @@ getsc_line(Source *s) cp = Xstring(s->xs, xp); while (*cp && ctype(*cp, C_IFSWS)) ++cp; - if (!*cp) + if (!*cp) { + histsave(&s->line, NULL, HIST_FLUSH, true); histsync(); + } #endif } if (interactive) From d09aca4175bf73db859360c44e3ed3502d07e844 Mon Sep 17 00:00:00 2001 From: tg Date: Mon, 6 Jul 2015 17:45:33 +0000 Subject: [PATCH 20/21] do the IFS_QUOTE dance right; this finally fixes ""$@ --- eval.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/eval.c b/eval.c index fbcb61d..0b585bc 100644 --- a/eval.c +++ b/eval.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.169 2015/05/23 17:43:19 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.170 2015/07/06 17:45:33 tg Exp $"); /* * string expansion @@ -291,21 +291,14 @@ expand( c = *sp++; break; case OQUOTE: - switch (word) { - case IFS_QUOTE: - /* """something */ - word = IFS_WORD; - break; - case IFS_WORD: - break; - default: + if (word != IFS_WORD) word = IFS_QUOTE; - break; - } tilde_ok = 0; quote = 1; continue; case CQUOTE: + if (word == IFS_QUOTE) + word = IFS_WORD; quote = st->quotew; continue; case COMSUB: From f463d9da7661095fa4deac47509bea26aeedbf44 Mon Sep 17 00:00:00 2001 From: tg Date: Mon, 6 Jul 2015 17:48:37 +0000 Subject: [PATCH 21/21] =?UTF-8?q?=E2=80=A2=20revert=20the=20cat=20hack=20f?= =?UTF-8?q?or=20realpath=20and=20rename=20=20=20=E2=80=A3=20I=20was=20conv?= =?UTF-8?q?inced=20by=20several=20that=20more=20magic=20is=20never=20the?= =?UTF-8?q?=20solution=20=E2=80=A2=20fix=20a=20comment:=20function=20cat?= =?UTF-8?q?=20already=20had=20precedence=20=E2=80=A2=20change=20cat=20load?= =?UTF-8?q?er=20to=20look=20for=20existence,=20FPATH=20included,=20before?= =?UTF-8?q?=20=20=20ditching=20the=20builtin;=20note=20that=20in=20manpage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Build.sh | 5 +---- check.t | 20 +++++--------------- exec.c | 43 +++++++++++++++++++++---------------------- funcs.c | 4 ++-- main.c | 4 ++-- mksh.1 | 23 +++++------------------ sh.h | 5 +++-- 7 files changed, 39 insertions(+), 65 deletions(-) diff --git a/Build.sh b/Build.sh index d75b15e..ec0d64c 100644 --- a/Build.sh +++ b/Build.sh @@ -1,5 +1,5 @@ #!/bin/sh -srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.680 2015/07/05 15:45:16 tg Exp $' +srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.681 2015/07/06 17:48:28 tg Exp $' #- # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013, 2014, 2015 @@ -2645,9 +2645,6 @@ MKSH_NOPROSPECTOFWORK disable jobs, co-processes, etc. (do not use) MKSH_NOPWNAM skip PAM calls, for -static on glibc or Solaris MKSH_NO_CMDLINE_EDITING disable command line editing code entirely MKSH_NO_DEPRECATED_WARNING omit warning when deprecated stuff is run -MKSH_NO_EXTERNAL_CAT omit hack to skip cat builtin when flags passed -MKSH_NO_EXTERNAL_REALPATH same for realpath builtin -MKSH_NO_EXTERNAL_RENAME same for rename builtin MKSH_NO_LIMITS omit ulimit code MKSH_NO_SIGSETJMP define if sigsetjmp is broken or not available MKSH_NO_SIGSUSPEND use sigprocmask+pause instead of sigsuspend diff --git a/check.t b/check.t index 34aa403..2b461d0 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.698 2015/07/05 19:37:11 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.699 2015/07/06 17:48:29 tg Exp $ # -*- mode: sh -*- #- # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, @@ -30,7 +30,7 @@ # (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date expected-stdout: - @(#)MIRBSD KSH R51 2015/07/05 + @(#)MIRBSD KSH R51 2015/07/06 description: Check version of shell. stdin: @@ -39,7 +39,7 @@ name: KSH_VERSION category: shell:legacy-no --- expected-stdout: - @(#)LEGACY KSH R51 2015/07/05 + @(#)LEGACY KSH R51 2015/07/06 description: Check version of legacy shell. stdin: @@ -8533,7 +8533,7 @@ description: Ensure concatenating behaviour matches other shells stdin: showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; } - #showargs 0 ""$@ + showargs 0 ""$@ x=; showargs 1 "$x"$@ set A; showargs 2 "${@:+}" n() { echo "$#"; } @@ -8553,6 +8553,7 @@ stdin: n "$@" n "$@""$e" expected-stdout: + <0> <> . <1> <> . <2> <> . 2 @@ -8568,17 +8569,6 @@ expected-stdout: 0 1 --- -name: varexpand-null-3a -description: - Ensure concatenating behaviour matches other shells - (currently broken cases) -expected-fail: yes -stdin: - showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; } - showargs 0 ""$@ -expected-stdout: - <0> <> . ---- name: print-funny-chars description: Check print builtin's capability to output designated characters diff --git a/exec.c b/exec.c index 3f8863c..bf8c4a8 100644 --- a/exec.c +++ b/exec.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.154 2015/07/05 15:45:17 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.155 2015/07/06 17:48:31 tg Exp $"); #ifndef MKSH_DEFAULT_EXECSHELL #define MKSH_DEFAULT_EXECSHELL "/bin/sh" @@ -551,6 +551,8 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap, } if ((tp = findcom(cp, FC_BI)) == NULL) errorf("%s: %s: %s", Tbuiltin, cp, "not a builtin"); + if (tp->type == CSHELL && tp->val.f == c_cat) + break; continue; } else if (tp->val.f == c_exec) { if (ap[1] == NULL) @@ -607,30 +609,19 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap, subst_exstat = 0; break; } -#if !defined(MKSH_NO_EXTERNAL_CAT) || \ - !defined(MKSH_NO_EXTERNAL_REALPATH) || \ - !defined(MKSH_NO_EXTERNAL_RENAME) - } else if ( -#ifndef MKSH_NO_EXTERNAL_CAT - tp->val.f == c_cat || -#endif -#ifndef MKSH_NO_EXTERNAL_REALPATH - tp->val.f == c_realpath || -#endif -#ifndef MKSH_NO_EXTERNAL_RENAME - tp->val.f == c_rename || -#endif - 0) { + } else if (tp->val.f == c_cat) { /* if we have any flags, do not use the builtin */ if (ap[1] && ap[1][0] == '-' && ap[1][1] != '\0' && /* argument, begins with -, is not - or -- */ - (ap[1][1] != '-' || ap[1][2] != '\0')) - /* don't look for builtins or functions */ - fcflags = FC_PATH; - else - /* go on, use the builtin */ - break; -#endif + (ap[1][1] != '-' || ap[1][2] != '\0')) { + struct tbl *ext_cat; + + ext_cat = findcom(Tcat, FC_PATH | FC_FUNC); + if (ext_cat && (ext_cat->type != CTALIAS || + (ext_cat->flag & ISSET))) + tp = ext_cat; + } + break; } else if (tp->val.f == c_trap) { t->u.evalflags &= ~DOTCOMEXEC; break; @@ -710,6 +701,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap, /* shell built-in */ case CSHELL: + do_call_builtin: rv = call_builtin(tp, (const char **)ap, null, resetspec); if (resetspec && tp->val.f == c_shift) { l_expand->argc = l_assign->argc; @@ -734,6 +726,11 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap, break; } if (include(tp->u.fpath, 0, NULL, false) < 0) { + if (!strcmp(cp, Tcat)) { + no_cat_in_FPATH: + tp = findcom(Tcat, FC_BI); + goto do_call_builtin; + } warningf(true, "%s: %s %s %s: %s", cp, "can't open", "function definition file", tp->u.fpath, cstrerror(errno)); @@ -742,6 +739,8 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap, } if (!(ftp = findfunc(cp, hash(cp), false)) || !(ftp->flag & ISSET)) { + if (!strcmp(cp, Tcat)) + goto no_cat_in_FPATH; warningf(true, "%s: %s %s", cp, "function not defined by", tp->u.fpath); rv = 127; diff --git a/funcs.c b/funcs.c index 64c7d2f..1be28e4 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.276 2015/07/05 19:37:14 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.277 2015/07/06 17:48:32 tg Exp $"); #if HAVE_KILLPG /* @@ -99,7 +99,7 @@ const struct builtin mkshbuiltins[] = { {Talias, c_alias}, {"*=break", c_brkcont}, {Tgbuiltin, c_builtin}, - {"cat", c_cat}, + {Tcat, c_cat}, {"cd", c_cd}, /* dash compatibility hack */ {"chdir", c_cd}, diff --git a/main.c b/main.c index eecea60..64fa3dd 100644 --- a/main.c +++ b/main.c @@ -34,7 +34,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.294 2015/07/05 19:37:16 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.295 2015/07/06 17:48:34 tg Exp $"); extern char **environ; @@ -87,7 +87,7 @@ static const char *initcoms[] = { NULL, /* this is what AT&T ksh seems to track, with the addition of emacs */ Talias, "-tU", - "cat", "cc", "chmod", "cp", "date", "ed", "emacs", "grep", "ls", + Tcat, "cc", "chmod", "cp", "date", "ed", "emacs", "grep", "ls", "make", "mv", "pr", "rm", "sed", "sh", "vi", "who", NULL, NULL }; diff --git a/mksh.1 b/mksh.1 index fb9666b..85dbda4 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.372 2015/07/05 19:37:17 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.373 2015/07/06 17:48:35 tg Exp $ .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -74,7 +74,7 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: July 5 2015 $ +.Dd $Mdocdate: July 6 2015 $ .\" .\" Check which macro package we use, and do other -mdoc setup. .\" @@ -3161,15 +3161,13 @@ If a is a single dash .Pq Sq - or absent, read from standard input. -Unless compiled with -.Dv MKSH_NO_EXTERNAL_CAT , -if any options are given, an external -.Xr cat 1 -utility is invoked instead if called from the shell. For direct builtin calls, the .Tn POSIX .Fl u option is supported as a no-op. +For calls from shell, if any options are given, an external +.Xr cat 1 +utility is preferred over the builtin. .Pp .It Xo .Ic cd @@ -3958,12 +3956,6 @@ it's also checked for existence and whether it is a directory; otherwise, returns 0 if the pathname either exists or can be created immediately, i.e. all but the last component exist and are directories. .Pp -Unless compiled with -.Dv MKSH_NO_EXTERNAL_REALPATH , -if any options are given and this is not a direct builtin call, an external -.Xr realpath 1 -utility is invoked instead. -.Pp .It Xo .Ic rename .Op Fl \- @@ -3978,11 +3970,6 @@ This builtin is intended for emergency situations where .Pa /bin/mv becomes unusable, and directly calls .Xr rename 2 . -Unless compiled with -.Dv MKSH_NO_EXTERNAL_RENAME , -if any options are given and this is not a direct builtin call, an external -.Xr rename 1 -utility is invoked instead. .Pp .It Ic return Op Ar status Returns from a function or diff --git a/sh.h b/sh.h index 74d4b57..23c7e5a 100644 --- a/sh.h +++ b/sh.h @@ -169,9 +169,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.733 2015/07/05 19:37:18 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.734 2015/07/06 17:48:37 tg Exp $"); #endif -#define MKSH_VERSION "R51 2015/07/05" +#define MKSH_VERSION "R51 2015/07/06" /* arithmetic types: C implementation */ #if !HAVE_CAN_INTTYPES @@ -821,6 +821,7 @@ EXTERN const char T_typeset[] E_INIT("=typeset"); #define Ttypeset (T_typeset + 1) /* "typeset" */ EXTERN const char Talias[] E_INIT("alias"); EXTERN const char Tunalias[] E_INIT("unalias"); +EXTERN const char Tcat[] E_INIT("cat"); EXTERN const char Tsgset[] E_INIT("*=set"); #define Tset (Tsgset + 2) /* "set" */ EXTERN const char Tsgexport[] E_INIT("*=export");