Merge remote-tracking branch 'mksh/master'
This commit is contained in:
3
Build.sh
3
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.681 2015/07/06 17:48:28 tg Exp $'
|
||||
#-
|
||||
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
# 2011, 2012, 2013, 2014, 2015
|
||||
@ -2654,7 +2654,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_LIMITS omit ulimit code
|
||||
MKSH_NO_SIGSETJMP define if sigsetjmp is broken or not available
|
||||
MKSH_NO_SIGSUSPEND use sigprocmask+pause instead of sigsuspend
|
||||
|
12
check.t
12
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.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/05/23
|
||||
@(#)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/05/23
|
||||
@(#)LEGACY KSH R51 2015/07/06
|
||||
description:
|
||||
Check version of legacy shell.
|
||||
stdin:
|
||||
@ -3583,7 +3583,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*$/
|
||||
---
|
||||
@ -3665,7 +3665,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*$/
|
||||
---
|
||||
@ -8599,6 +8599,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 "$#"; }
|
||||
@ -8618,6 +8619,7 @@ stdin:
|
||||
n "$@"
|
||||
n "$@""$e"
|
||||
expected-stdout:
|
||||
<0> <> .
|
||||
<1> <> .
|
||||
<2> <> .
|
||||
2
|
||||
|
24
dot.mkshrc
24
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.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
|
||||
|
||||
@ -112,7 +113,7 @@ function chpwd {
|
||||
\:
|
||||
}
|
||||
\chpwd .
|
||||
function cd {
|
||||
cd() {
|
||||
\builtin cd "$@" || \return $?
|
||||
\chpwd "$@"
|
||||
}
|
||||
@ -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
|
||||
|
8
edit.c
8
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
|
||||
@ -3101,7 +3101,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);
|
||||
@ -4390,8 +4390,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);
|
||||
|
15
eval.c
15
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:
|
||||
|
46
exec.c
46
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.155 2015/07/06 17:48:31 tg Exp $");
|
||||
|
||||
#ifndef MKSH_DEFAULT_EXECSHELL
|
||||
#define MKSH_DEFAULT_EXECSHELL UNIXROOT "/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
|
||||
@ -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,25 +609,19 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
||||
subst_exstat = 0;
|
||||
break;
|
||||
}
|
||||
#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)
|
||||
*/
|
||||
/* 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 */
|
||||
(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;
|
||||
#endif
|
||||
} else if (tp->val.f == c_trap) {
|
||||
t->u.evalflags &= ~DOTCOMEXEC;
|
||||
break;
|
||||
@ -705,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;
|
||||
@ -729,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));
|
||||
@ -737,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;
|
||||
@ -1657,7 +1661,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 =
|
||||
@ -1665,7 +1669,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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1711,11 +1714,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
|
||||
|
23
funcs.c
23
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.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},
|
||||
@ -227,7 +227,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 *);
|
||||
|
||||
@ -445,7 +445,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);
|
||||
@ -541,7 +541,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));
|
||||
@ -1310,7 +1310,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;
|
||||
@ -1320,7 +1320,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
|
||||
@ -1967,8 +1966,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;
|
||||
@ -1993,6 +1993,7 @@ c_read(const char **wp)
|
||||
goto c_read_readloop;
|
||||
}
|
||||
|
||||
c_read_didread:
|
||||
switch (readmode) {
|
||||
case READALL:
|
||||
if (bytesread == 0) {
|
||||
@ -2015,7 +2016,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;
|
||||
@ -2078,7 +2079,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;
|
||||
|
103
histrap.c
103
histrap.c
@ -27,7 +27,7 @@
|
||||
#include <sys/file.h>
|
||||
#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.148 2015/07/05 19:53:45 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);
|
||||
|
||||
@ -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)
|
||||
{
|
||||
@ -223,7 +226,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,18 +363,17 @@ 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;
|
||||
int ret;
|
||||
char *p, *q;
|
||||
|
||||
/* Back up over last histsave */
|
||||
if (histptr >= history && last_line != hist_source->line) {
|
||||
@ -381,22 +383,12 @@ 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, HIST_STORE, 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
|
||||
@ -578,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;
|
||||
}
|
||||
@ -612,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;
|
||||
|
||||
@ -631,15 +626,38 @@ 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, *cp;
|
||||
static char *enqueued = NULL;
|
||||
char **hp, *c;
|
||||
const char *ccp;
|
||||
|
||||
strdupx(c, cmd, APERM);
|
||||
if ((cp = strchr(c, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
if (svmode == HIST_DISCARD) {
|
||||
afree(enqueued, APERM);
|
||||
enqueued = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
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 (svmode != HIST_APPEND) {
|
||||
if (ignoredups && !strcmp(c, *histptr)
|
||||
#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY
|
||||
&& !histsync()
|
||||
@ -649,12 +667,33 @@ histsave(int *lnp, const char *cmd, bool dowrite MKSH_A_UNUSED, bool ignoredups)
|
||||
return;
|
||||
}
|
||||
++*lnp;
|
||||
}
|
||||
|
||||
#if HAVE_PERSISTENT_HISTORY
|
||||
if (dowrite && histfd != -1)
|
||||
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;
|
||||
}
|
||||
|
||||
hp = histptr;
|
||||
|
||||
if (++hp >= history + histsize) {
|
||||
@ -707,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;
|
||||
|
||||
@ -864,7 +905,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;
|
||||
|
22
lex.c
22
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.204 2015/07/05 19:53:46 tg Exp $");
|
||||
|
||||
/*
|
||||
* states while lexing word
|
||||
@ -1461,16 +1461,23 @@ 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;
|
||||
if (!*cp)
|
||||
if (!*cp) {
|
||||
histsave(&s->line, NULL, HIST_FLUSH, true);
|
||||
histsync();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (interactive)
|
||||
@ -1495,6 +1502,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 +1514,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 +1532,7 @@ set_prompt(int to, Source *s)
|
||||
char *cp = substitute(ps1, 0);
|
||||
strdupx(prompt, cp, saved_atemp);
|
||||
}
|
||||
current_lineno = saved_lineno;
|
||||
quitenv(NULL);
|
||||
}
|
||||
break;
|
||||
|
6
main.c
6
main.c
@ -34,7 +34,7 @@
|
||||
#include <locale.h>
|
||||
#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.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
|
||||
};
|
||||
@ -825,6 +825,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;
|
||||
|
12
mirhash.h
12
mirhash.h
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright © 2011, 2014
|
||||
* Thorsten Glaser <tg@mirbsd.org>
|
||||
* Copyright © 2011, 2014, 2015
|
||||
* Thorsten “mirabilos” Glaser <tg@mirbsd.org>
|
||||
*
|
||||
* Provided that these terms and disclaimer and all copyright notices
|
||||
* are retained or reproduced in an accompanying document, permission
|
||||
@ -44,7 +44,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
__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) \
|
||||
|
45
misc.c
45
misc.c
@ -30,7 +30,7 @@
|
||||
#include <grp.h>
|
||||
#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.236 2015/07/05 14:58:33 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;
|
||||
@ -1256,17 +1255,20 @@ 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) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1277,18 +1279,19 @@ 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++) {
|
||||
i = c * rows + r;
|
||||
if (i < n) {
|
||||
shf_fprintf(shf, "%*s", max_col,
|
||||
(*func)(str, max_oct, i, arg));
|
||||
if (c + 1 < cols)
|
||||
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);
|
||||
}
|
||||
|
33
mksh.1
33
mksh.1
@ -1,5 +1,5 @@
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.367 2015/05/23 17:43:20 tg Exp $
|
||||
.\" $OpenBSD: ksh.1,v 1.159 2015/03/25 12:10:52 jca 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,
|
||||
.\" 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: May 23 2015 $
|
||||
.Dd $Mdocdate: July 6 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,
|
||||
@ -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.
|
||||
@ -2145,7 +2146,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
|
||||
@ -3160,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
|
||||
@ -3296,9 +3295,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
|
||||
@ -3832,7 +3831,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 +3851,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;
|
||||
|
16
sh.h
16
sh.h
@ -172,9 +172,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.734 2015/07/06 17:48:37 tg Exp $");
|
||||
#endif
|
||||
#define MKSH_VERSION "R51 2015/05/23"
|
||||
#define MKSH_VERSION "R51 2015/07/06"
|
||||
|
||||
/* arithmetic types: C implementation */
|
||||
#if !HAVE_CAN_INTTYPES
|
||||
@ -861,6 +861,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");
|
||||
@ -1665,6 +1666,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;
|
||||
|
||||
@ -1791,7 +1799,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
|
||||
@ -1934,7 +1942,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);
|
||||
|
Reference in New Issue
Block a user