get rid of special "POSIX"ish mode

This commit is contained in:
tg 2005-07-04 12:27:28 +00:00
parent 3fb44287d4
commit e392a30930
10 changed files with 85 additions and 284 deletions

14
check.t
View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.19 2005/07/04 11:57:55 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.20 2005/07/04 12:27:25 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@ -3637,14 +3637,18 @@ name: xxx-param-subst-qmark-1
description:
Check suppresion of error message with null string. According to
POSIX, it shouldn't print the error as 'word' isn't ommitted.
ksh88, Solaris /bin/sh and /usr/xpg4/bin/sh all print the error?!
ksh88, Solaris /bin/sh and /usr/xpg4/bin/sh all print the error,
that's why the condition is reversed.
stdin:
unset foo
x=
echo x${foo?$x}
expected-exit: 1
expected-fail: yes
expected-stderr-pattern: !/not set/
# POSIX
#expected-fail: yes
#expected-stderr-pattern: !/not set/
# common use
expected-stderr-pattern: /parameter null or not set/
---
name: xxx-param-_-1
description:
@ -3658,7 +3662,7 @@ description:
env-setup: !HOME=/sweet!
stdin:
echo ${A=a=}~ b=~ c=d~ ~
set -o posix
set +o braceexpand
echo ${A=a=}~ b=~ c=d~ ~
expected-stdout:
a=/sweet b=/sweet c=d~ /sweet

9
eval.c
View File

@ -1,4 +1,4 @@
/** $MirOS: src/bin/mksh/eval.c,v 1.4 2005/06/08 22:34:03 tg Exp $ */
/** $MirOS: src/bin/mksh/eval.c,v 1.5 2005/07/04 12:27:25 tg Exp $ */
/* $OpenBSD: eval.c,v 1.27 2005/03/30 17:16:37 deraadt Exp $ */
#include "sh.h"
@ -6,7 +6,7 @@
#include <dirent.h>
#include <pwd.h>
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.4 2005/06/08 22:34:03 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.5 2005/07/04 12:27:25 tg Exp $");
/*
* string expansion
@ -613,8 +613,9 @@ expand(char *cp, /* input word */
break;
case '=':
/* Note first unquoted = for ~ */
if (!(f & DOTEMP_) && (!Flag(FPOSIX)
|| (f & DOASNTILDE)) && !saw_eq) {
if (!(f & DOTEMP_) && !saw_eq &&
(Flag(FBRACEEXPAND) ||
(f & DOASNTILDE))) {
saw_eq = 1;
tilde_ok = 1;
}

12
exec.c
View File

@ -1,11 +1,11 @@
/** $MirOS: src/bin/mksh/exec.c,v 1.5 2005/05/25 14:07:29 tg Exp $ */
/** $MirOS: src/bin/mksh/exec.c,v 1.6 2005/07/04 12:27:25 tg Exp $ */
/* $OpenBSD: exec.c,v 1.41 2005/03/30 17:16:37 deraadt Exp $ */
#include "sh.h"
#include <sys/stat.h>
#include <ctype.h>
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.5 2005/05/25 14:07:29 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.6 2005/07/04 12:27:25 tg Exp $");
static int comexec(struct op *, struct tbl *volatile, char **,
int volatile);
@ -844,14 +844,6 @@ findcom(const char *name, int flags)
}
if (!tp && (flags & FC_REGBI) && tbi && (tbi->flag & REG_BI))
tp = tbi;
/* todo: posix says non-special/non-regular builtins must
* be triggered by some user-controllable means like a
* special directory in PATH. Requires modifications to
* the search() function. Tracked aliases should be
* modified to allow tracking of builtin commands.
* This should be under control of the FPOSIX flag.
* If this is changed, also change c_whence...
*/
if (!tp && (flags & FC_UNREGBI) && tbi)
tp = tbi;
if (!tp && (flags & FC_PATH) && !(flags & FC_DEFPATH)) {

83
funcs.c
View File

@ -1,4 +1,4 @@
/** $MirOS: src/bin/mksh/funcs.c,v 1.12 2005/06/24 15:40:38 tg Exp $ */
/** $MirOS: src/bin/mksh/funcs.c,v 1.13 2005/07/04 12:27:26 tg Exp $ */
/* $OpenBSD: c_ksh.c,v 1.27 2005/03/30 17:16:37 deraadt Exp $ */
/* $OpenBSD: c_sh.c,v 1.29 2005/03/30 17:16:37 deraadt Exp $ */
/* $OpenBSD: c_test.c,v 1.17 2005/03/30 17:16:37 deraadt Exp $ */
@ -13,7 +13,7 @@
#include <ulimit.h>
#endif
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.12 2005/06/24 15:40:38 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.13 2005/07/04 12:27:26 tg Exp $");
int
c_cd(char **wp)
@ -1076,10 +1076,7 @@ c_fgbg(char **wp)
rv = j_resume(*wp, bg);
else
rv = j_resume("%%", bg);
/* POSIX says fg shall return 0 (unless an error occurs).
* at&t ksh returns the exit value of the job...
*/
return (bg || Flag(FPOSIX)) ? 0 : rv;
return bg ? 0 : rv;
}
struct kill_info {
@ -1164,12 +1161,6 @@ c_kill(char **wp)
else
shprintf("%d\n", n);
}
} else if (Flag(FPOSIX)) {
p = null;
for (i = 1; i < NSIG; i++, p = space)
if (sigtraps[i].name)
shprintf("%s%s", p, sigtraps[i].name);
shprintf(newline);
} else {
int w, j;
int mess_width;
@ -1222,8 +1213,7 @@ void
getopts_reset(int val)
{
if (val >= 1) {
ksh_getopt_reset(&user_opt,
GF_NONAME | (Flag(FPOSIX) ? 0 : GF_PLUSOPT));
ksh_getopt_reset(&user_opt, GF_NONAME | GF_PLUSOPT);
user_opt.optind = user_opt.uoptind = val;
}
}
@ -1799,33 +1789,32 @@ c_eval(char **wp)
return 1;
s = pushs(SWORDS, ATEMP);
s->u.strv = wp + builtin_opt.optind;
if (!Flag(FPOSIX)) {
/*
* Handle case where the command is empty due to failed
* command substitution, eg, eval "$(false)".
* In this case, shell() will not set/change exstat (because
* compiled tree is empty), so will use this value.
* subst_exstat is cleared in execute(), so should be 0 if
* there were no substitutions.
*
* A strict reading of POSIX says we don't do this (though
* it is traditionally done). [from 1003.2-1992]
* 3.9.1: Simple Commands
* ... If there is a command name, execution shall
* continue as described in 3.9.1.1. If there
* is no command name, but the command contained a command
* substitution, the command shall complete with the exit
* status of the last command substitution
* 3.9.1.1: Command Search and Execution
* ...(1)...(a) If the command name matches the name of
* a special built-in utility, that special built-in
* utility shall be invoked.
* 3.14.5: Eval
* ... If there are no arguments, or only null arguments,
* eval shall return an exit status of zero.
*/
exstat = subst_exstat;
}
/*
* Handle case where the command is empty due to failed
* command substitution, eg, eval "$(false)".
* In this case, shell() will not set/change exstat (because
* compiled tree is empty), so will use this value.
* subst_exstat is cleared in execute(), so should be 0 if
* there were no substitutions.
*
* A strict reading of POSIX says we don't do this (though
* it is traditionally done). [from 1003.2-1992]
* 3.9.1: Simple Commands
* ... If there is a command name, execution shall
* continue as described in 3.9.1.1. If there
* is no command name, but the command contained a command
* substitution, the command shall complete with the exit
* status of the last command substitution
* 3.9.1.1: Command Search and Execution
* ...(1)...(a) If the command name matches the name of
* a special built-in utility, that special built-in
* utility shall be invoked.
* 3.14.5: Eval
* ... If there are no arguments, or only null arguments,
* eval shall return an exit status of zero.
*/
exstat = subst_exstat;
savef = Flag(FERREXIT);
Flag(FERREXIT) = 0;
@ -2009,7 +1998,7 @@ c_set(char **wp)
* (subst_exstat is cleared in execute() so that it will be 0
* if there are no command substitutions).
*/
return Flag(FPOSIX) ? 0 : subst_exstat;
return subst_exstat;
}
int
@ -2387,11 +2376,7 @@ c_test(char **wp)
}
if (argc == 1) {
opnd1 = (*te.getopnd)(&te, TO_NONOP, 1);
/* Historically, -t by itself test if fd 1
* is a file descriptor, but POSIX says its
* a string test...
*/
if (!Flag(FPOSIX) && strcmp(opnd1, "-t") == 0)
if (strcmp(opnd1, "-t") == 0)
break;
res = (*te.eval)(&te, TO_STNZE, opnd1,
NULL, 1);
@ -2507,10 +2492,8 @@ test_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2,
if (opnd1 && !bi_getn(opnd1, &res)) {
te->flags |= TEF_ERROR;
res = 0;
} else {
/* generate error if in FPOSIX mode? */
} else
res = isatty(opnd1 ? res : 0);
}
return res;
case TO_FILUID: /* -O */
return test_stat(opnd1, &b1) == 0 && b1.st_uid == ksheuid;

9
jobs.c
View File

@ -1,4 +1,4 @@
/** $MirOS: src/bin/mksh/jobs.c,v 1.2 2005/05/23 16:23:19 tg Exp $ */
/** $MirOS: src/bin/mksh/jobs.c,v 1.3 2005/07/04 12:27:26 tg Exp $ */
/* $OpenBSD: jobs.c,v 1.34 2005/03/30 17:16:37 deraadt Exp $ */
#include "sh.h"
@ -7,7 +7,7 @@
#include <sys/time.h>
#include <sys/wait.h>
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.2 2005/05/23 16:23:19 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.3 2005/07/04 12:27:26 tg Exp $");
/* Order important! */
#define PRUNNING 0
@ -1310,9 +1310,8 @@ j_lookup(const char *cp, int *ecodep)
for (j = job_list; j != NULL; j = j->next)
if (j->last_proc && j->last_proc->pid == job)
return j;
/* ...then look for process group (this is non-POSIX),
* but should not break anything (so FPOSIX isn't used).
*/
/* ...then look for process group (this is non-POSIX,
* but should not break anything */
for (j = job_list; j != NULL; j = j->next)
if (j->pgrp && j->pgrp == job)
return j;

36
lex.c
View File

@ -1,11 +1,11 @@
/** $MirOS: src/bin/mksh/lex.c,v 1.4 2005/06/08 22:34:03 tg Exp $ */
/** $MirOS: src/bin/mksh/lex.c,v 1.5 2005/07/04 12:27:26 tg Exp $ */
/* $OpenBSD: lex.c,v 1.36 2005/03/30 17:16:37 deraadt Exp $ */
#include "sh.h"
#include <ctype.h>
#include <libgen.h>
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.4 2005/06/08 22:34:03 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.5 2005/07/04 12:27:26 tg Exp $");
/* Structure to keep track of the lexing state and the various pieces of info
* needed for each particular state. */
@ -138,11 +138,7 @@ yylex(int cf)
}
if (source->flags & SF_ALIAS) { /* trailing ' ' in alias definition */
source->flags &= ~SF_ALIAS;
/* In POSIX mode, a trailing space only counts if we are
* parsing a simple command
*/
if (!Flag(FPOSIX) || (cf & CMDWORD))
cf |= ALIAS;
cf |= ALIAS;
}
/* Initial state: one of SBASE SHEREDELIM SWORD SASPAREN */
@ -323,22 +319,20 @@ yylex(int cf)
* $ ` \.").
*/
statep->ls_sbquote.indquotes = 0;
if (!Flag(FPOSIX)) {
Lex_state *s = statep;
Lex_state *base = state_info.base;
while (1) {
for (; s != base; s--) {
if (s->ls_state == SDQUOTE) {
statep->ls_sbquote.indquotes = 1;
break;
}
Lex_state *s = statep;
Lex_state *base = state_info.base;
while (1) {
for (; s != base; s--) {
if (s->ls_state == SDQUOTE) {
statep->ls_sbquote.indquotes = 1;
break;
}
if (s != base)
break;
if (!(s = s->ls_info.base))
break;
base = s-- - STATE_BSIZE;
}
if (s != base)
break;
if (!(s = s->ls_info.base))
break;
base = s-- - STATE_BSIZE;
}
break;
case QCHAR:

11
main.c
View File

@ -1,4 +1,4 @@
/** $MirOS: src/bin/mksh/main.c,v 1.17 2005/07/04 11:57:55 tg Exp $ */
/** $MirOS: src/bin/mksh/main.c,v 1.18 2005/07/04 12:27:26 tg Exp $ */
/* $OpenBSD: main.c,v 1.38 2005/03/30 17:16:37 deraadt Exp $ */
/* $OpenBSD: tty.c,v 1.8 2005/03/30 17:16:37 deraadt Exp $ */
/* $OpenBSD: io.c,v 1.21 2005/03/30 17:16:37 deraadt Exp $ */
@ -13,7 +13,7 @@
#include <time.h>
#endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.17 2005/07/04 11:57:55 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.18 2005/07/04 12:27:26 tg Exp $");
const char ksh_version[] = "@(#)MIRBSD KSH R23 2005/07/04";
@ -152,9 +152,7 @@ main(int argc, char *argv[])
Flag(FNOHUP) = 1;
/* Turn on brace expansion by default. At&t kshs that have
* alternation always have it on. BUT, posix doesn't have
* brace expansion, so set this before setting up FPOSIX
* (change_flag() clears FBRACEEXPAND when FPOSIX is set).
* alternation always have it on.
*/
Flag(FBRACEEXPAND) = 1;
@ -807,8 +805,7 @@ bi_errorf(const char *fmt, ...)
* non-interactive shells to exit.
* XXX odd use of KEEPASN; also may not want LERROR here
*/
if ((builtin_flag & SPEC_BI) ||
(Flag(FPOSIX) && (builtin_flag & KEEPASN))) {
if (builtin_flag & SPEC_BI) {
builtin_argv0 = NULL;
unwind(LERROR);
}

12
misc.c
View File

@ -1,4 +1,4 @@
/** $MirOS: src/bin/mksh/misc.c,v 1.4 2005/05/25 13:46:01 tg Exp $ */
/** $MirOS: src/bin/mksh/misc.c,v 1.5 2005/07/04 12:27:27 tg Exp $ */
/* $OpenBSD: misc.c,v 1.28 2005/03/30 17:16:37 deraadt Exp $ */
/* $OpenBSD: path.c,v 1.12 2005/03/30 17:16:37 deraadt Exp $ */
@ -7,7 +7,7 @@
#include <sys/param.h> /* for MAXPATHLEN */
#include <sys/stat.h>
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.4 2005/05/25 13:46:01 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.5 2005/07/04 12:27:27 tg Exp $");
short chtypes[UCHAR_MAX+1]; /* type bits for unsigned char */
@ -251,6 +251,10 @@ change_flag(enum sh_flag f,
{
int oldval;
/* disabled functionality */
if (f == FPOSIX)
return;
oldval = Flag(f);
Flag(f) = newval;
if (f == FMONITOR) {
@ -268,8 +272,6 @@ change_flag(enum sh_flag f,
setuid(ksheuid);
setegid(kshegid = kshgid = getgid());
setgid(kshegid);
} else if (f == FPOSIX && newval) {
Flag(FBRACEEXPAND) = 0;
}
/* Changing interactive flag? */
if (f == FTALKING) {
@ -404,7 +406,7 @@ parse_args(char **argv,
(argv[go.optind][0] == '-' || argv[go.optind][0] == '+') &&
argv[go.optind][1] == '\0') {
/* lone - clears -v and -x flags */
if (argv[go.optind][0] == '-' && !Flag(FPOSIX))
if (argv[go.optind][0] == '-')
Flag(FVERBOSE) = Flag(FXTRACE) = 0;
/* set skips lone - or + option */
go.optind++;

177
mksh.1
View File

@ -1,4 +1,4 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.11 2005/07/04 12:07:40 tg Exp $
.\" $MirOS: src/bin/mksh/mksh.1,v 1.12 2005/07/04 12:27:27 tg Exp $
.\" $OpenBSD: ksh.1,v 1.99 2005/05/25 16:52:06 jaredy Exp $
.\" $OpenBSD: sh.1tbl,v 1.53 2004/12/10 01:56:56 jaredy Exp $
.\"
@ -810,12 +810,6 @@ the
and the newline are stripped; otherwise, both the
.Ql \e
and the character following are unchanged.
.Pp
.Sy Note :
See
.Sx POSIX mode
below for a special rule regarding
differences in quoting when the shell is in POSIX mode.
.Ss Aliases
There are two types of aliases: normal command aliases and tracked aliases.
Command aliases are normally used as a short hand for a long or often used
@ -2269,168 +2263,6 @@ trapped) will have their default effect in a function.
The EXIT trap, if set in a function, will be executed after the function
returns.
.El
.Ss POSIX mode
The shell is intended to be POSIX compliant;
however, in some cases, POSIX behaviour is contrary either to
the original Korn shell behaviour or to user convenience.
How the shell behaves in these cases is determined by the state of the
.Ic posix
option
.Pq Ic set -o posix .
If it is on, the POSIX behaviour is followed; otherwise, it is not.
.Pp
The following is a list of things that are affected by the state of the
.Ic posix
option:
.Bl -bullet
.It
Reading of
.Ev $ENV .
If not in
.Ic posix
mode, the
.Ev ENV
parameter is not expanded and included when the shell starts.
.It
Occurrences of
.Ic \e\&"
inside double quoted
.Ic `..`
command substitutions.
In POSIX mode, the
.Ic \e\&"
is interpreted when the command is interpreted;
in non-POSIX mode,
the backslash is stripped before the command substitution is interpreted.
For example,
.Ic echo \&"`echo \e\&"hi\e\&"`\&"
produces
.Dq \&"hi\&"
in POSIX mode,
.Dq hi
in non-POSIX mode.
To avoid problems, use the
.Ic $(...)\&
form of command substitution.
.It
.Ic kill -l
output.
In POSIX mode, only signal names are listed (in a single line);
in non-POSIX mode,
signal numbers, names, and descriptions are printed (in columns).
In the future, a new option
.Pq Fl v No perhaps
will be added to distinguish the two behaviours.
.It
.Ic fg
exit status.
In POSIX mode, the exit status is 0 if no errors occur;
in non-POSIX mode, the exit status is that of the last foregrounded job.
.It
.Ic eval
exit status.
If
.Ic eval
gets to see an empty command (i.e.\&
.Ic eval `false` ) ,
its exit status in POSIX mode will be 0.
In non-POSIX mode,
it will be the exit status of the last command substitution that was
done in the processing of the arguments to
.Ic eval
(or 0 if there were no command substitutions).
.It
.Ic getopts .
In POSIX mode, options must start with a
.Ql - ;
in non-POSIX mode, options can start with either
.Ql -
or
.Ql + .
.It
Brace expansion (also known as alternation).
In POSIX mode, brace expansion is disabled;
in non-POSIX mode, brace expansion is enabled.
Note that
.Ic set -o posix
automatically turns the
.Ic braceexpand
option off; however, it can be explicitly turned on later.
.It
.Ic set - .
In POSIX mode, this does not clear the
.Ic verbose
or
.Ic xtrace
options; in non-POSIX mode, it does.
.It
.Ic set
exit status.
In POSIX mode, the exit status of
.Ic set
is 0 if there are no errors;
in non-POSIX mode, the exit status is that of any
command substitutions performed in generating the
.Ic set
command.
For example,
.Ic set -- `false`; echo $?\&
prints 0 in POSIX mode, 1 in non-POSIX mode.
This construct is used in most shell scripts that use the old
.Xr getopt 1
command.
.It
Argument expansion of the
.Ic alias ,
.Ic export ,
.Ic readonly ,
and
.Ic typeset
commands.
In POSIX mode, normal argument expansion is done; in non-POSIX mode,
field splitting, file globbing, brace expansion, and (normal) tilde expansion
are turned off, while assignment tilde expansion is turned on.
.It
Signal specification.
In POSIX mode, signals can be specified as digits, only
if signal numbers match POSIX values
(i.e. HUP=1, INT=2, QUIT=3, ABRT=6, KILL=9, ALRM=14, and TERM=15);
in non-POSIX mode, signals can always be digits.
.It
Alias expansion.
In POSIX mode, alias expansion is only carried out when reading command words;
in non-POSIX mode, alias expansion is carried out on any
word following an alias that ended in a space.
For example, the following
.Ic for
loop uses parameter
.Sq i
in POSIX mode and
.Sq j
in non-POSIX mode:
.Bd -literal -offset indent
alias a='for ' i='j'
a i in 1 2; do echo i=$i j=$j; done
.Ed
.Pp
.It
.Ic test .
In POSIX mode, the expression
.Sq Fl t
(preceded by some number of
.Sq \&!
arguments) is always true as it is a non-zero length string;
in non-POSIX mode, it tests if file descriptor 1 is a
.Xr tty 4
(i.e. the
.Ar fd
argument to the
.Fl t
test may be left out and defaults to 1).
.It
Tilde expansion after equal signs (not assignments) is disabled,
although not strictly forbidden by POSIX, for consistency with other shells.
.El
.Ss Strict Bourne shell mode
When the
.Ic sh
@ -3414,6 +3246,8 @@ the value of
Background jobs are run with lower priority.
.It Ic braceexpand
Enable brace expansion (a.k.a. alternation).
This is enabled by default.
If disabled, tilde expansion after an equals sign is disabled as a side effect.
.It Ic emacs
Enable BRL emacs-like command-line editing (interactive shells only); see
.Sx Emacs editing mode .
@ -3478,11 +3312,6 @@ See the
and
.Ic pwd
commands above for more details.
.It Ic posix
Enable POSIX mode.
See
.Sx POSIX mode
above.
.It Ic restricted
The shell is a restricted shell.
This option can only be used when the shell is invoked.

6
syn.c
View File

@ -1,9 +1,9 @@
/** $MirOS: src/bin/mksh/syn.c,v 1.1 2005/05/23 03:06:10 tg Exp $ */
/** $MirOS: src/bin/mksh/syn.c,v 1.2 2005/07/04 12:27:28 tg Exp $ */
/* $OpenBSD: syn.c,v 1.22 2005/03/30 17:16:37 deraadt Exp $ */
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.1 2005/05/23 03:06:10 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.2 2005/07/04 12:27:28 tg Exp $");
struct nesting_state {
int start_token; /* token than began nesting (eg, FOR) */
@ -778,7 +778,7 @@ assign_command(char *s)
{
char c = *s;
if (Flag(FPOSIX) || !*s)
if (!*s)
return 0;
return (c == 'a' && strcmp(s, "alias") == 0) ||
(c == 'e' && strcmp(s, "export") == 0) ||