collective R54 release preparation multi-merger:
install both lksh and mksh manpages from Build.sh (Martijn Dekker) spelling fixes (Larry Hynes) manpage improvements (Martijn Dekker) initial port to Harvey-OS’ APEX (Ronald G. Minnich, Elbing Miss, Álvaro Jurado) more from komh’s OS/2 port (KO Myung-Hun)
This commit is contained in:
parent
3aac3c30b5
commit
7b4bee7e58
42
Build.sh
42
Build.sh
|
@ -1,5 +1,5 @@
|
|||
#!/bin/sh
|
||||
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.706 2016/11/07 16:55:51 tg Exp $'
|
||||
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.707 2016/11/11 23:31:29 tg Exp $'
|
||||
#-
|
||||
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
# 2011, 2012, 2013, 2014, 2015, 2016
|
||||
|
@ -584,7 +584,7 @@ if test -d $tfn || test -d $tfn.exe; then
|
|||
exit 1
|
||||
fi
|
||||
rmf a.exe* a.out* conftest.c conftest.exe* *core core.* ${tfn}* *.bc *.dbg \
|
||||
*.ll *.o *.gen Rebuild.sh lft no signames.inc test.sh x vv.out
|
||||
*.ll *.o *.gen *.cat1 Rebuild.sh lft no signames.inc test.sh x vv.out
|
||||
|
||||
SRCS="lalloc.c eval.c exec.c expr.c funcs.c histrap.c jobs.c"
|
||||
SRCS="$SRCS lex.c main.c misc.c shf.c syn.c tree.c var.c"
|
||||
|
@ -755,6 +755,24 @@ GNU/kFreeBSD)
|
|||
Haiku)
|
||||
add_cppflags -DMKSH_ASSUME_UTF8; HAVE_ISSET_MKSH_ASSUME_UTF8=1
|
||||
;;
|
||||
Harvey)
|
||||
add_cppflags -D_POSIX_SOURCE
|
||||
add_cppflags -D_LIMITS_EXTENSION
|
||||
add_cppflags -D_BSD_EXTENSION
|
||||
add_cppflags -D_SUSV2_SOURCE
|
||||
add_cppflags -D_GNU_SOURCE
|
||||
add_cppflags -DMKSH_ASSUME_UTF8; HAVE_ISSET_MKSH_ASSUME_UTF8=1
|
||||
add_cppflags -DMKSH_NO_CMDLINE_EDITING
|
||||
add_cppflags -DMKSH__NO_SETEUGID
|
||||
oswarn=' and will currently not work'
|
||||
add_cppflags -DMKSH_UNEMPLOYED
|
||||
add_cppflags -DMKSH_NOPROSPECTOFWORK
|
||||
# these taken from Harvey-OS github and need re-checking
|
||||
add_cppflags -D_setjmp=setjmp -D_longjmp=longjmp
|
||||
: "${HAVE_CAN_NO_EH_FRAME=0}"
|
||||
: "${HAVE_CAN_FNOSTRICTALIASING=0}"
|
||||
: "${HAVE_CAN_FSTACKPROTECTORSTRONG=0}"
|
||||
;;
|
||||
HP-UX)
|
||||
;;
|
||||
Interix)
|
||||
|
@ -833,12 +851,14 @@ OpenBSD)
|
|||
OS/2)
|
||||
HAVE_TERMIOS_H=0
|
||||
HAVE_MKNOD=0 # setmode() incompatible
|
||||
oswarn="; it is currently being ported"
|
||||
oswarn="; it is currently being ported, get it from"
|
||||
oswarn="$oswarn${nl}https://github.com/komh/mksh-os2 in the meanwhile"
|
||||
check_categories="$check_categories nosymlink"
|
||||
: "${CC=gcc}"
|
||||
: "${SIZE=: size}"
|
||||
add_cppflags -DMKSH_UNEMPLOYED
|
||||
add_cppflags -DMKSH_NOPROSPECTOFWORK
|
||||
add_cppflags -DMKSH_NO_LIMITS
|
||||
;;
|
||||
OSF1)
|
||||
HAVE_SIG_T=0 # incompatible
|
||||
|
@ -2347,7 +2367,7 @@ addsrcs '!' HAVE_STRLCPY strlcpy.c
|
|||
addsrcs USE_PRINTF_BUILTIN printf.c
|
||||
test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN
|
||||
test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose"
|
||||
add_cppflags -DMKSH_BUILD_R=539
|
||||
add_cppflags -DMKSH_BUILD_R=541
|
||||
|
||||
$e $bi$me: Finished configuration testing, now producing output.$ao
|
||||
|
||||
|
@ -2593,8 +2613,8 @@ esac
|
|||
tcfn=$mkshexe
|
||||
test $cm = combine || v "$CC $CFLAGS $LDFLAGS -o $tcfn $lobjs $LIBS $ccpr"
|
||||
test -f $tcfn || exit 1
|
||||
test 1 = $r || v "$NROFF -mdoc <'$srcdir/mksh.1' >$tfn.cat1" || \
|
||||
rmf $tfn.cat1
|
||||
test 1 = $r || v "$NROFF -mdoc <'$srcdir/lksh.1' >lksh.cat1" || rmf lksh.cat1
|
||||
test 1 = $r || v "$NROFF -mdoc <'$srcdir/mksh.1' >mksh.cat1" || rmf mksh.cat1
|
||||
test 0 = $eq && v $SIZE $tcfn
|
||||
i=install
|
||||
test -f /usr/ucb/$i && i=/usr/ucb/$i
|
||||
|
@ -2608,12 +2628,14 @@ if test $legacy = 0; then
|
|||
fi
|
||||
$e
|
||||
$e Installing the manual:
|
||||
if test -f $tfn.cat1; then
|
||||
$e "# $i -c -o root -g bin -m 444 $tfn.cat1" \
|
||||
"/usr/share/man/cat1/$tfn.0"
|
||||
if test -f mksh.cat1; then
|
||||
$e "# $i -c -o root -g bin -m 444 lksh.cat1" \
|
||||
"/usr/share/man/cat1/lksh.0"
|
||||
$e "# $i -c -o root -g bin -m 444 mksh.cat1" \
|
||||
"/usr/share/man/cat1/mksh.0"
|
||||
$e or
|
||||
fi
|
||||
$e "# $i -c -o root -g bin -m 444 $tfn.1 /usr/share/man/man1/$tfn.1"
|
||||
$e "# $i -c -o root -g bin -m 444 lksh.1 mksh.1 /usr/share/man/man1/"
|
||||
$e
|
||||
$e Run the regression test suite: ./test.sh
|
||||
$e Please also read the sample file dot.mkshrc and the fine manual.
|
||||
|
|
4
Makefile
4
Makefile
|
@ -1,4 +1,4 @@
|
|||
# $MirOS: src/bin/mksh/Makefile,v 1.153 2016/11/07 16:58:45 tg Exp $
|
||||
# $MirOS: src/bin/mksh/Makefile,v 1.154 2016/11/11 23:31:30 tg Exp $
|
||||
#-
|
||||
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
# 2011, 2012, 2013, 2014, 2015, 2016
|
||||
|
@ -57,7 +57,7 @@ CPPFLAGS+= -DMKSH_ASSUME_UTF8 -DMKSH_DISABLE_DEPRECATED \
|
|||
-DHAVE_SETGROUPS=1 -DHAVE_STRERROR=0 -DHAVE_STRSIGNAL=0 \
|
||||
-DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \
|
||||
-DHAVE_SYS_ERRLIST_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 \
|
||||
-DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=539
|
||||
-DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=541
|
||||
CPPFLAGS+= -D${${PROG:L}_tf:C/(Mir${MAN:E}{0,1}){2}/4/:S/x/mksh_BUILD/:U}
|
||||
CPPFLAGS+= -I.
|
||||
COPTS+= -std=c89 -Wall
|
||||
|
|
8
check.t
8
check.t
|
@ -1,4 +1,4 @@
|
|||
# $MirOS: src/bin/mksh/check.t,v 1.755 2016/11/07 16:58:45 tg Exp $
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.756 2016/11/11 23:31:31 tg Exp $
|
||||
# -*- mode: sh -*-
|
||||
#-
|
||||
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
|
@ -30,7 +30,7 @@
|
|||
# (2013/12/02 20:39:44) http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
|
||||
|
||||
expected-stdout:
|
||||
@(#)MIRBSD KSH R53 2016/11/07
|
||||
@(#)MIRBSD KSH R54 2016/11/11
|
||||
description:
|
||||
Check version of shell.
|
||||
stdin:
|
||||
|
@ -39,7 +39,7 @@ name: KSH_VERSION
|
|||
category: shell:legacy-no
|
||||
---
|
||||
expected-stdout:
|
||||
@(#)LEGACY KSH R53 2016/11/07
|
||||
@(#)LEGACY KSH R54 2016/11/11
|
||||
description:
|
||||
Check version of legacy shell.
|
||||
stdin:
|
||||
|
@ -4948,7 +4948,7 @@ name: integer-base-check-flat
|
|||
description:
|
||||
Check behaviour does not match POSuX (except if set -o posix),
|
||||
because a not type-safe scripting language has *no* business
|
||||
interpreting the string "010" as octal numer eight (dangerous).
|
||||
interpreting the string "010" as octal number eight (dangerous).
|
||||
stdin:
|
||||
echo 1 "$("$__progname" -c 'echo :$((10))/$((010)),$((0x10)):')" .
|
||||
echo 2 "$("$__progname" -o posix -c 'echo :$((10))/$((010)),$((0x10)):')" .
|
||||
|
|
31
edit.c
31
edit.c
|
@ -28,7 +28,7 @@
|
|||
|
||||
#ifndef MKSH_NO_CMDLINE_EDITING
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.310 2016/11/11 21:13:21 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.311 2016/11/11 23:31:33 tg Exp $");
|
||||
|
||||
/*
|
||||
* in later versions we might use libtermcap for this, but since external
|
||||
|
@ -258,7 +258,8 @@ x_print_expansions(int nwords, char * const *words, bool is_command)
|
|||
break;
|
||||
/* All in same directory? */
|
||||
if (i == nwords) {
|
||||
while (prefix_len > 0 && words[0][prefix_len - 1] != '/')
|
||||
while (prefix_len > 0 &&
|
||||
!mksh_cdirsep(words[0][prefix_len - 1]))
|
||||
prefix_len--;
|
||||
use_copy = true;
|
||||
XPinit(l, nwords + 1);
|
||||
|
@ -338,7 +339,7 @@ x_glob_hlp_tilde_and_rem_qchar(char *s, bool magic_flag)
|
|||
* and if so, discern "~foo/bar" and "~/baz" from "~blah";
|
||||
* if we have a directory part (the former), try to expand
|
||||
*/
|
||||
if (*s == '~' && (cp = strchr(s, '/')) != NULL) {
|
||||
if (*s == '~' && (cp = mksh_sdirsep(s)) != NULL) {
|
||||
/* ok, so split into "~foo"/"bar" or "~"/"baz" */
|
||||
*cp++ = 0;
|
||||
/* try to expand the tilde */
|
||||
|
@ -593,7 +594,7 @@ x_locate_word(const char *buf, int buflen, int pos, int *startp,
|
|||
* like file globbing.
|
||||
*/
|
||||
for (p = start; p < end; p++)
|
||||
if (buf[p] == '/')
|
||||
if (mksh_cdirsep(buf[p]))
|
||||
break;
|
||||
iscmd = p == end;
|
||||
}
|
||||
|
@ -657,7 +658,7 @@ x_cf_glob(int *flagsp, const char *buf, int buflen, int pos, int *startp,
|
|||
}
|
||||
}
|
||||
|
||||
if (*toglob == '~' && !vstrchr(toglob, '/')) {
|
||||
if (*toglob == '~' && !mksh_vdirsep(toglob)) {
|
||||
/* neither for '~foo' (but '~foo/bar') */
|
||||
*flagsp |= XCF_IS_NOSPACE;
|
||||
goto dont_add_glob;
|
||||
|
@ -746,13 +747,15 @@ x_basename(const char *s, const char *se)
|
|||
if (s == se)
|
||||
return (0);
|
||||
|
||||
/* Skip trailing slashes */
|
||||
for (p = se - 1; p > s && *p == '/'; p--)
|
||||
;
|
||||
for (; p > s && *p != '/'; p--)
|
||||
;
|
||||
if (*p == '/' && p + 1 < se)
|
||||
p++;
|
||||
/* skip trailing directory separators */
|
||||
p = se - 1;
|
||||
while (p > s && mksh_cdirsep(*p))
|
||||
--p;
|
||||
/* drop last component */
|
||||
while (p > s && !mksh_cdirsep(*p))
|
||||
--p;
|
||||
if (mksh_cdirsep(*p) && p + 1 < se)
|
||||
++p;
|
||||
|
||||
return (p - s);
|
||||
}
|
||||
|
@ -2783,7 +2786,7 @@ do_complete(
|
|||
* append a space if this is a single non-directory match
|
||||
* and not a parameter or homedir substitution
|
||||
*/
|
||||
if (nwords == 1 && words[0][nlen - 1] != '/' &&
|
||||
if (nwords == 1 && !mksh_cdirsep(words[0][nlen - 1]) &&
|
||||
!(flags & XCF_IS_NOSPACE)) {
|
||||
x_ins(T1space);
|
||||
}
|
||||
|
@ -5404,7 +5407,7 @@ complete_word(int cmd, int count)
|
|||
* append a space if this is a non-directory match
|
||||
* and not a parameter or homedir substitution
|
||||
*/
|
||||
if (match_len > 0 && match[match_len - 1] != '/' &&
|
||||
if (match_len > 0 && !mksh_cdirsep(match[match_len - 1]) &&
|
||||
!(flags & XCF_IS_NOSPACE))
|
||||
rval = putbuf(T1space, 1, false);
|
||||
}
|
||||
|
|
14
eval.c
14
eval.c
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.193 2016/09/01 12:59:09 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.194 2016/11/11 23:31:34 tg Exp $");
|
||||
|
||||
/*
|
||||
* string expansion
|
||||
|
@ -1576,7 +1576,7 @@ globit(XString *xs, /* dest string */
|
|||
* SunOS 4.1.3 does this...
|
||||
*/
|
||||
if ((check & GF_EXCHECK) && xp > Xstring(*xs, xp) &&
|
||||
xp[-1] == '/' && !S_ISDIR(lstatb.st_mode) &&
|
||||
mksh_cdirsep(xp[-1]) && !S_ISDIR(lstatb.st_mode) &&
|
||||
(!S_ISLNK(lstatb.st_mode) ||
|
||||
stat_check() < 0 || !S_ISDIR(statb.st_mode)))
|
||||
return;
|
||||
|
@ -1586,7 +1586,7 @@ globit(XString *xs, /* dest string */
|
|||
* directory
|
||||
*/
|
||||
if (((check & GF_MARKDIR) && (check & GF_GLOBBED)) &&
|
||||
xp > Xstring(*xs, xp) && xp[-1] != '/' &&
|
||||
xp > Xstring(*xs, xp) && !mksh_cdirsep(xp[-1]) &&
|
||||
(S_ISDIR(lstatb.st_mode) ||
|
||||
(S_ISLNK(lstatb.st_mode) && stat_check() > 0 &&
|
||||
S_ISDIR(statb.st_mode)))) {
|
||||
|
@ -1601,11 +1601,11 @@ globit(XString *xs, /* dest string */
|
|||
|
||||
if (xp > Xstring(*xs, xp))
|
||||
*xp++ = '/';
|
||||
while (*sp == '/') {
|
||||
while (mksh_cdirsep(*sp)) {
|
||||
Xcheck(*xs, xp);
|
||||
*xp++ = *sp++;
|
||||
}
|
||||
np = strchr(sp, '/');
|
||||
np = mksh_sdirsep(sp);
|
||||
if (np != NULL) {
|
||||
se = np;
|
||||
/* don't assume '/', can be multiple kinds */
|
||||
|
@ -1713,8 +1713,8 @@ maybe_expand_tilde(const char *p, XString *dsp, char **dpp, bool isassign)
|
|||
|
||||
Xinit(ts, tp, 16, ATEMP);
|
||||
/* : only for DOASNTILDE form */
|
||||
while (p[0] == CHAR && p[1] != '/' && (!isassign || p[1] != ':'))
|
||||
{
|
||||
while (p[0] == CHAR && !mksh_cdirsep(p[1]) &&
|
||||
(!isassign || p[1] != ':')) {
|
||||
Xcheck(ts, tp);
|
||||
*tp++ = p[1];
|
||||
p += 2;
|
||||
|
|
14
exec.c
14
exec.c
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.185 2016/11/11 21:13:23 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.186 2016/11/11 23:31:34 tg Exp $");
|
||||
|
||||
#ifndef MKSH_DEFAULT_EXECSHELL
|
||||
#define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh"
|
||||
|
@ -672,7 +672,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
|||
rv = subst_exstat;
|
||||
goto Leave;
|
||||
} else if (!tp) {
|
||||
if (Flag(FRESTRICTED) && vstrchr(cp, '/')) {
|
||||
if (Flag(FRESTRICTED) && mksh_vdirsep(cp)) {
|
||||
warningf(true, Tf_sD_s, cp, "restricted");
|
||||
rv = 1;
|
||||
goto Leave;
|
||||
|
@ -1123,7 +1123,7 @@ findcom(const char *name, int flags)
|
|||
char *fpath;
|
||||
union mksh_cchack npath;
|
||||
|
||||
if (vstrchr(name, '/')) {
|
||||
if (mksh_vdirsep(name)) {
|
||||
insert = 0;
|
||||
/* prevent FPATH search below */
|
||||
flags &= ~FC_FUNC;
|
||||
|
@ -1240,8 +1240,12 @@ search_access(const char *fn, int mode)
|
|||
eno = errno;
|
||||
return (eno ? eno : EACCES);
|
||||
}
|
||||
#ifdef __OS2__
|
||||
/* treat all files as executable on OS/2 */
|
||||
sb.st_mode &= S_IXUSR | S_IXGRP | S_IXOTH;
|
||||
#endif
|
||||
if (mode == X_OK && (!S_ISREG(sb.st_mode) ||
|
||||
!(sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))))
|
||||
!(sb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
|
||||
/* access(2) may say root can execute everything */
|
||||
return (S_ISDIR(sb.st_mode) ? EISDIR : EACCES);
|
||||
return (0);
|
||||
|
@ -1263,7 +1267,7 @@ search_path(const char *name, const char *lpath,
|
|||
size_t namelen;
|
||||
int ec = 0, ev;
|
||||
|
||||
if (vstrchr(name, '/')) {
|
||||
if (mksh_vdirsep(name)) {
|
||||
if ((ec = search_access(name, mode)) == 0) {
|
||||
search_path_ok:
|
||||
if (errnop)
|
||||
|
|
8
lksh.1
8
lksh.1
|
@ -1,4 +1,4 @@
|
|||
.\" $MirOS: src/bin/mksh/lksh.1,v 1.19 2016/08/25 16:21:33 tg Exp $
|
||||
.\" $MirOS: src/bin/mksh/lksh.1,v 1.20 2016/11/11 23:31:35 tg Exp $
|
||||
.\"-
|
||||
.\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015, 2016
|
||||
.\" mirabilos <m@mirbsd.org>
|
||||
|
@ -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: August 25 2016 $
|
||||
.Dd $Mdocdate: November 11 2016 $
|
||||
.\"
|
||||
.\" Check which macro package we use, and do other -mdoc setup.
|
||||
.\"
|
||||
|
@ -221,8 +221,8 @@ for the versions this document applies to.
|
|||
.Nm
|
||||
uses
|
||||
.Tn POSIX
|
||||
arithmetics, which has quite a few implications:
|
||||
The data type for arithmetics is the host
|
||||
arithmetic, which has quite a few implications:
|
||||
The data type for arithmetic operations is the host
|
||||
.Tn ISO
|
||||
C
|
||||
.Vt long
|
||||
|
|
4
main.c
4
main.c
|
@ -34,7 +34,7 @@
|
|||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.320 2016/10/26 22:55:51 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.321 2016/11/11 23:31:35 tg Exp $");
|
||||
|
||||
extern char **environ;
|
||||
|
||||
|
@ -227,7 +227,7 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
|
|||
ccp = kshname;
|
||||
goto begin_parsing_kshname;
|
||||
while ((i = ccp[argi++])) {
|
||||
if (i == '/') {
|
||||
if (mksh_cdirsep(i)) {
|
||||
ccp += argi;
|
||||
begin_parsing_kshname:
|
||||
argi = 0;
|
||||
|
|
32
misc.c
32
misc.c
|
@ -30,7 +30,7 @@
|
|||
#include <grp.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.248 2016/11/11 21:13:25 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.249 2016/11/11 23:31:35 tg Exp $");
|
||||
|
||||
#define KSH_CHVT_FLAG
|
||||
#ifdef MKSH_SMALL
|
||||
|
@ -391,7 +391,7 @@ parse_args(const char **argv,
|
|||
*/
|
||||
if (*p != '-')
|
||||
for (q = p; *q; )
|
||||
if (*q++ == '/')
|
||||
if (mksh_cdirsep(*q++))
|
||||
p = q;
|
||||
Flag(FLOGIN) = (*p == '-');
|
||||
opts = cmd_opts;
|
||||
|
@ -1443,14 +1443,14 @@ do_realpath(const char *upath)
|
|||
|
||||
while (*ip) {
|
||||
/* skip slashes in input */
|
||||
while (*ip == '/')
|
||||
while (mksh_cdirsep(*ip))
|
||||
++ip;
|
||||
if (!*ip)
|
||||
break;
|
||||
|
||||
/* get next pathname component from input */
|
||||
tp = ip;
|
||||
while (*ip && *ip != '/')
|
||||
while (*ip && !mksh_cdirsep(*ip))
|
||||
++ip;
|
||||
len = ip - tp;
|
||||
|
||||
|
@ -1462,7 +1462,7 @@ do_realpath(const char *upath)
|
|||
else if (len == 2 && tp[1] == '.') {
|
||||
/* strip off last pathname component */
|
||||
while (xp > Xstring(xs, xp))
|
||||
if (*--xp == '/')
|
||||
if (mksh_cdirsep(*--xp))
|
||||
break;
|
||||
/* then continue with the next one */
|
||||
continue;
|
||||
|
@ -1485,7 +1485,7 @@ do_realpath(const char *upath)
|
|||
/* lstat failed */
|
||||
if (errno == ENOENT) {
|
||||
/* because the pathname does not exist */
|
||||
while (*ip == '/')
|
||||
while (mksh_cdirsep(*ip))
|
||||
/* skip any trailing slashes */
|
||||
++ip;
|
||||
/* no more components left? */
|
||||
|
@ -1545,6 +1545,7 @@ do_realpath(const char *upath)
|
|||
/* assert: xp == xs.beg => start of path */
|
||||
|
||||
/* exactly two leading slashes? (SUSv4 3.266) */
|
||||
/* @komh do NOT use mksh_cdirsep() here */
|
||||
if (ip[1] == '/' && ip[2] != '/') {
|
||||
/* keep them, e.g. for UNC pathnames */
|
||||
Xput(xs, xp, '/');
|
||||
|
@ -1570,7 +1571,7 @@ do_realpath(const char *upath)
|
|||
* if source path had a trailing slash, check if target path
|
||||
* is not a non-directory existing file
|
||||
*/
|
||||
if (ip > ipath && ip[-1] == '/') {
|
||||
if (ip > ipath && mksh_cdirsep(ip[-1])) {
|
||||
if (stat(Xstring(xs, xp), &sb)) {
|
||||
if (errno != ENOENT)
|
||||
goto notfound;
|
||||
|
@ -1639,7 +1640,7 @@ make_path(const char *cwd, const char *file,
|
|||
|
||||
if (c == '.')
|
||||
c = file[2];
|
||||
if (c == '/' || c == '\0')
|
||||
if (mksh_cdirsep(c) || c == '\0')
|
||||
use_cdpath = false;
|
||||
}
|
||||
|
||||
|
@ -1661,7 +1662,7 @@ make_path(const char *cwd, const char *file,
|
|||
XcheckN(*xsp, xp, len);
|
||||
memcpy(xp, cwd, len);
|
||||
xp += len;
|
||||
if (cwd[len - 1] != '/')
|
||||
if (!mksh_cdirsep(cwd[len - 1]))
|
||||
Xput(*xsp, xp, '/');
|
||||
}
|
||||
*phys_pathp = Xlength(*xsp, xp);
|
||||
|
@ -1669,7 +1670,7 @@ make_path(const char *cwd, const char *file,
|
|||
XcheckN(*xsp, xp, plen);
|
||||
memcpy(xp, plist, plen);
|
||||
xp += plen;
|
||||
if (plist[plen - 1] != '/')
|
||||
if (!mksh_cdirsep(plist[plen - 1]))
|
||||
Xput(*xsp, xp, '/');
|
||||
rval = 1;
|
||||
}
|
||||
|
@ -1711,9 +1712,14 @@ simplify_path(char *p)
|
|||
return;
|
||||
case '/':
|
||||
/* exactly two leading slashes? (SUSv4 3.266) */
|
||||
/* @komh no mksh_cdirsep() here! */
|
||||
if (p[1] == '/' && p[2] != '/')
|
||||
/* keep them, e.g. for UNC pathnames */
|
||||
++p;
|
||||
#ifdef __OS2__
|
||||
/* FALLTHROUGH */
|
||||
case '\\':
|
||||
#endif
|
||||
needslash = true;
|
||||
break;
|
||||
default:
|
||||
|
@ -1723,14 +1729,14 @@ simplify_path(char *p)
|
|||
|
||||
while (*ip) {
|
||||
/* skip slashes in input */
|
||||
while (*ip == '/')
|
||||
while (mksh_cdirsep(*ip))
|
||||
++ip;
|
||||
if (!*ip)
|
||||
break;
|
||||
|
||||
/* get next pathname component from input */
|
||||
tp = ip;
|
||||
while (*ip && *ip != '/')
|
||||
while (*ip && !mksh_cdirsep(*ip))
|
||||
++ip;
|
||||
len = ip - tp;
|
||||
|
||||
|
@ -1750,7 +1756,7 @@ simplify_path(char *p)
|
|||
strip_last_component:
|
||||
/* strip off last pathname component */
|
||||
while (dp > sp)
|
||||
if (*--dp == '/')
|
||||
if (mksh_cdirsep(*--dp))
|
||||
break;
|
||||
} else {
|
||||
/* relative path, at its beginning */
|
||||
|
|
34
mksh.1
34
mksh.1
|
@ -1,4 +1,4 @@
|
|||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.419 2016/11/11 22:17:09 tg Exp $
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.420 2016/11/11 23:31:36 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,
|
||||
|
@ -1060,7 +1060,7 @@ For
|
|||
and
|
||||
.Dq Li \eu#### ,
|
||||
.Dq #
|
||||
means a hexadecimal digit, of thich there may be none up to four or eight;
|
||||
means a hexadecimal digit, of which there may be none up to four or eight;
|
||||
these escapes translate a Unicode codepoint to UTF-8.
|
||||
Furthermore,
|
||||
.Dq Li \eE
|
||||
|
@ -2602,7 +2602,7 @@ This also affects implicit conversion to integer, for example as done by the
|
|||
.Ic let
|
||||
command.
|
||||
.Em Never
|
||||
use unchecked user input, e.g. from the environment, in arithmetics!
|
||||
use unchecked user input, e.g. from the environment, in an arithmetic context!
|
||||
.Pp
|
||||
Expressions are calculated using signed arithmetic and the
|
||||
.Vt mksh_ari_t
|
||||
|
@ -4899,7 +4899,7 @@ If necessary, values are either truncated or space padded
|
|||
to fit the field width.
|
||||
.It Fl l
|
||||
Lower case attribute.
|
||||
All upper case characters in values are converted to lower case.
|
||||
All upper case ASCII characters in values are converted to lower case.
|
||||
(In the original Korn shell, this parameter meant
|
||||
.Dq long integer
|
||||
when used with the
|
||||
|
@ -4923,7 +4923,7 @@ is lazily evaluated at the time
|
|||
.Ar name
|
||||
is accessed.
|
||||
This can be used by functions to access variables whose names are
|
||||
passed as parametres, instead of using
|
||||
passed as parameters, instead of using
|
||||
.Ic eval .
|
||||
.It Fl p
|
||||
Print complete
|
||||
|
@ -4964,7 +4964,7 @@ option).
|
|||
This option is not in the original Korn shell.
|
||||
.It Fl u
|
||||
Upper case attribute.
|
||||
All lower case characters in values are converted to upper case.
|
||||
All lower case ASCII characters in values are converted to upper case.
|
||||
(In the original Korn shell, this parameter meant
|
||||
.Dq unsigned integer
|
||||
when used with the
|
||||
|
@ -5381,11 +5381,11 @@ to behave even more
|
|||
compliant in places where the defaults or opinions differ.
|
||||
Note that
|
||||
.Nm mksh
|
||||
will still operate with unsigned 32-bit arithmetics; use
|
||||
will still operate with unsigned 32-bit arithmetic; use
|
||||
.Nm lksh
|
||||
if arithmetics on the host
|
||||
if arithmetic on the host
|
||||
.Vt long
|
||||
data type, complete with ISO C Undefined Behaviour, are required;
|
||||
data type, complete with ISO C Undefined Behaviour, is required;
|
||||
refer to the
|
||||
.Xr lksh 1
|
||||
manual page for details.
|
||||
|
@ -5586,7 +5586,7 @@ Moves the cursor to the beginning of the edited input line.
|
|||
.Op Ar n
|
||||
.No \*(ha[C , \*(ha[c
|
||||
.Xc
|
||||
Uppercase the first character in the next
|
||||
Uppercase the first ASCII character in the next
|
||||
.Ar n
|
||||
words, leaving the cursor past the end of the last word.
|
||||
.It clear\-screen: \*(ha[\*(haL
|
||||
|
@ -6586,8 +6586,8 @@ This shell is based on the public domain 7th edition Bourne shell clone by
|
|||
.An Charles Forsyth ,
|
||||
who kindly agreed to, in countries where the Public Domain status of the work
|
||||
may not be valid, grant a copyright licence to the general public to deal in
|
||||
the work without restriction and permission to sublicence derivates under the
|
||||
terms of any (OSI approved) Open Source licence,
|
||||
the work without restriction and permission to sublicence derivatives under
|
||||
the terms of any (OSI approved) Open Source licence,
|
||||
and parts of the BRL shell by
|
||||
.An Doug A. Gwyn ,
|
||||
.An Doug Kingston ,
|
||||
|
@ -6629,7 +6629,7 @@ The complete legalese is at:
|
|||
has a different scope model from
|
||||
.At
|
||||
.Nm ksh ,
|
||||
which leads to subtile differences in semantics for identical builtins.
|
||||
which leads to subtle differences in semantics for identical builtins.
|
||||
This can cause issues with a
|
||||
.Ic nameref
|
||||
to suddenly point to a local variable by accident; fixing this is hard.
|
||||
|
@ -6644,9 +6644,9 @@ foo \*(Ba bar \*(Ba& read \-p baz # will, however, do so
|
|||
.Ed
|
||||
.Pp
|
||||
.Nm mksh
|
||||
provides a consistent set of 32-bit integer arithmetics, both signed
|
||||
and unsigned, with defined wraparound and sign of the result of a
|
||||
remainder operation, even (defying POSIX) on 36-bit and 64-bit systems.
|
||||
provides a consistent 32-bit integer arithmetic implementation, both
|
||||
signed and unsigned, with sign of the result of a remainder operation
|
||||
and wraparound defined, even (defying POSIX) on 36-bit and 64-bit systems.
|
||||
.Pp
|
||||
.Nm mksh
|
||||
provides a consistent, clear interface normally.
|
||||
|
@ -6701,7 +6701,7 @@ The truncation process involved when changing
|
|||
.Ev HISTFILE
|
||||
does not free old history entries (leaks memory) and leaks
|
||||
old entries into the new history if their line numbers are
|
||||
not overwritten by same-numer entries from the persistent
|
||||
not overwritten by same-number entries from the persistent
|
||||
history file; truncating the on-disc file to
|
||||
.Ev HISTSIZE
|
||||
lines has always been broken and prone to history file corruption
|
||||
|
|
44
sh.h
44
sh.h
|
@ -175,9 +175,9 @@
|
|||
#endif
|
||||
|
||||
#ifdef EXTERN
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.790 2016/11/07 16:58:48 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.791 2016/11/11 23:31:38 tg Exp $");
|
||||
#endif
|
||||
#define MKSH_VERSION "R53 2016/11/07"
|
||||
#define MKSH_VERSION "R54 2016/11/11"
|
||||
|
||||
/* arithmetic types: C implementation */
|
||||
#if !HAVE_CAN_INTTYPES
|
||||
|
@ -578,7 +578,7 @@ char *ucstrstr(char *, const char *);
|
|||
#define mkssert(e) do { } while (/* CONSTCOND */ 0)
|
||||
#endif
|
||||
|
||||
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 539)
|
||||
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 541)
|
||||
#error Must run Build.sh to compile this.
|
||||
extern void thiswillneverbedefinedIhope(void);
|
||||
int
|
||||
|
@ -1350,7 +1350,7 @@ EXTERN mksh_ari_t x_lins E_INIT(24);
|
|||
/* Determine the location of the system (common) profile */
|
||||
|
||||
#ifndef MKSH_DEFAULT_PROFILEDIR
|
||||
#define MKSH_DEFAULT_PROFILEDIR "/etc"
|
||||
#define MKSH_DEFAULT_PROFILEDIR MKSH_UNIXROOT "/etc"
|
||||
#endif
|
||||
|
||||
#define MKSH_SYSTEM_PROFILE MKSH_DEFAULT_PROFILEDIR "/profile"
|
||||
|
@ -1748,8 +1748,6 @@ typedef struct XString {
|
|||
Area *areap;
|
||||
} XString;
|
||||
|
||||
typedef char *XStringP;
|
||||
|
||||
/* initialise expandable string */
|
||||
#define XinitN(xs, length, area) do { \
|
||||
(xs).len = (length); \
|
||||
|
@ -1825,6 +1823,15 @@ typedef struct {
|
|||
#define XPclose(x) aresize2((x).beg, XPsize(x), sizeof(void *), ATEMP)
|
||||
#define XPfree(x) afree((x).beg, ATEMP)
|
||||
|
||||
/* for print_columns */
|
||||
|
||||
struct columnise_opts {
|
||||
struct shf *shf;
|
||||
char linesep;
|
||||
bool do_last;
|
||||
bool prefcol;
|
||||
};
|
||||
|
||||
/*
|
||||
* Lexer internals
|
||||
*/
|
||||
|
@ -2021,7 +2028,7 @@ void flushcom(bool);
|
|||
int search_access(const char *, int);
|
||||
const char *search_path(const char *, const char *, int, int *);
|
||||
void pr_menu(const char * const *);
|
||||
void pr_list(char * const *);
|
||||
void pr_list(struct columnise_opts *, char * const *);
|
||||
int herein(struct ioword *, char **);
|
||||
/* expr.c */
|
||||
int evaluate(const char *, mksh_ari_t *, int, bool);
|
||||
|
@ -2122,8 +2129,8 @@ void runtrap(Trap *, bool);
|
|||
void cleartraps(void);
|
||||
void restoresigs(void);
|
||||
void settrap(Trap *, const char *);
|
||||
int block_pipe(void);
|
||||
void restore_pipe(int);
|
||||
bool block_pipe(void);
|
||||
void restore_pipe(void);
|
||||
int setsig(Trap *, sig_t, int);
|
||||
void setexecsig(Trap *, int);
|
||||
#if HAVE_FLOCK || HAVE_LOCK_FCNTL
|
||||
|
@ -2237,9 +2244,9 @@ void ksh_getopt_reset(Getopt *, int);
|
|||
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,
|
||||
void print_columns(struct columnise_opts *, unsigned int,
|
||||
void (*)(char *, size_t, unsigned int, const void *),
|
||||
const void *, size_t, size_t, bool);
|
||||
const void *, size_t, size_t);
|
||||
void strip_nuls(char *, size_t)
|
||||
MKSH_A_BOUNDED(__string__, 1, 2);
|
||||
ssize_t blocking_read(int, char *, size_t)
|
||||
|
@ -2420,13 +2427,26 @@ extern int tty_init_fd(void); /* initialise tty_fd, tty_devtty */
|
|||
})
|
||||
#define mksh_abspath(s) __extension__({ \
|
||||
const char *mksh_abspath_s = (s); \
|
||||
(mksh_abspath_s[0] == '/' || (ksh_isalphx(mksh_abspath_s[0]) && \
|
||||
(mksh_cdirsep(mksh_abspath_s[0]) || \
|
||||
(ksh_isalphx(mksh_abspath_s[0]) && \
|
||||
mksh_abspath_s[1] == ':')); \
|
||||
})
|
||||
#define mksh_cdirsep(c) __extension__({ \
|
||||
char mksh_cdirsep_c = (c); \
|
||||
(mksh_cdirsep_c == '/' || mksh_cdirsep_c == '\\'); \
|
||||
})
|
||||
/*
|
||||
* I've seen mksh_sdirsep(s) and mksh_vdirsep(s) but need to think
|
||||
* more about the OS/2 port (and, possibly, toy with it) before I
|
||||
* can merge this upstream, but good job so far @komh, thanks!
|
||||
*/
|
||||
#else
|
||||
#define binopen2(path,flags) open((path), (flags) | O_BINARY)
|
||||
#define binopen3(path,flags,mode) open((path), (flags) | O_BINARY, (mode))
|
||||
#define mksh_abspath(s) ((s)[0] == '/')
|
||||
#define mksh_cdirsep(c) ((c) == '/')
|
||||
#define mksh_sdirsep(s) strchr((s), '/')
|
||||
#define mksh_vdirsep(s) vstrchr((s), '/')
|
||||
#endif
|
||||
|
||||
/* be sure not to interfere with anyone else's idea about EXTERN */
|
||||
|
|
25
var.c
25
var.c
|
@ -28,7 +28,7 @@
|
|||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.208 2016/10/22 23:56:50 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.209 2016/11/11 23:31:39 tg Exp $");
|
||||
|
||||
/*-
|
||||
* Variables
|
||||
|
@ -133,7 +133,7 @@ initvar(void)
|
|||
struct tbl *tp;
|
||||
|
||||
ktinit(APERM, &specials,
|
||||
/* currently 15 specials: 75% of 32 = 2^5 */
|
||||
/* currently 18 specials: 75% of 32 = 2^5 */
|
||||
5);
|
||||
while (i < V_MAX - 1) {
|
||||
tp = ktenter(&specials, initvar_names[i],
|
||||
|
@ -1149,6 +1149,13 @@ makenv(void)
|
|||
/* setstr can't fail here */
|
||||
setstr(vp, val, KSH_RETURN_ERROR);
|
||||
}
|
||||
#ifdef __OS2__
|
||||
/* these special variables are not exported */
|
||||
if (!strcmp(vp->name, "BEGINLIBPATH") ||
|
||||
!strcmp(vp->name, "ENDLIBPATH") ||
|
||||
!strcmp(vp->name, "LIBPATHSTRICT"))
|
||||
continue;
|
||||
#endif
|
||||
XPput(denv, vp->val.s);
|
||||
}
|
||||
if (l->flags & BF_STOPENV)
|
||||
|
@ -1274,6 +1281,13 @@ setspec(struct tbl *vp)
|
|||
int st;
|
||||
|
||||
switch ((st = special(vp->name))) {
|
||||
#ifdef __OS2__
|
||||
case V_BEGINLIBPATH:
|
||||
case V_ENDLIBPATH:
|
||||
case V_LIBPATHSTRICT:
|
||||
setextlibpath(vp->name, str_val(vp));
|
||||
return;
|
||||
#endif
|
||||
#if HAVE_PERSISTENT_HISTORY
|
||||
case V_HISTFILE:
|
||||
sethistfile(str_val(vp));
|
||||
|
@ -1396,6 +1410,13 @@ unsetspec(struct tbl *vp)
|
|||
*/
|
||||
|
||||
switch (special(vp->name)) {
|
||||
#ifdef __OS2__
|
||||
case V_BEGINLIBPATH:
|
||||
case V_ENDLIBPATH:
|
||||
case V_LIBPATHSTRICT:
|
||||
setextlibpath(vp->name, "");
|
||||
return;
|
||||
#endif
|
||||
#if HAVE_PERSISTENT_HISTORY
|
||||
case V_HISTFILE:
|
||||
sethistfile(NULL);
|
||||
|
|
11
var_spec.h
11
var_spec.h
|
@ -19,7 +19,7 @@
|
|||
*/
|
||||
|
||||
#if defined(VARSPEC_DEFNS)
|
||||
__RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.9 2016/07/25 21:02:13 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.10 2016/11/11 23:31:39 tg Exp $");
|
||||
#define FN(name) /* nothing */
|
||||
#elif defined(VARSPEC_ENUMS)
|
||||
#define FN(name) V_##name,
|
||||
|
@ -40,13 +40,22 @@ F0(NONE)
|
|||
|
||||
/* 1 and up are special variables */
|
||||
FN(BASHPID)
|
||||
#ifdef __OS2__
|
||||
FN(BEGINLIBPATH)
|
||||
#endif
|
||||
FN(COLUMNS)
|
||||
#ifdef __OS2__
|
||||
FN(ENDLIBPATH)
|
||||
#endif
|
||||
FN(EPOCHREALTIME)
|
||||
#if HAVE_PERSISTENT_HISTORY
|
||||
FN(HISTFILE)
|
||||
#endif
|
||||
FN(HISTSIZE)
|
||||
FN(IFS)
|
||||
#ifdef __OS2__
|
||||
FN(LIBPATHSTRICT)
|
||||
#endif
|
||||
FN(LINENO)
|
||||
FN(LINES)
|
||||
FN(OPTIND)
|
||||
|
|
Loading…
Reference in New Issue