1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Yet more misc. cleanups; rm SHOPT_PFSH, SHOPT_TYPEDEF

Notable changes:
- Remove SHOPT_PFSH compile-time option and associated code.
  This was meant to work with Solaris rights profiles, see:
  https://docs.oracle.com/cd/E23824_01/html/821-1461/profiles-1.html#REFMAN1profiles-1
  But it has been obsolete for years as Solaris stopped using
  it in its shipped ksh several OS versions ago, preferring a
  library-based wrapper around ksh and other shells.
  Nonetheless I experimented with the option on Solaris 11.4.
  Result: no external command will run; output of unitialised
  memory in error message. So it's already fallen victim to bit
  rot. There's nothing interesting here, so just get rid.
- Remove SHOPT_TYPEDEF compile-time option (but keep the code!).
  Turning it off caused the build to fail. It may be possible to
  fix it, but the type definition code is integral to ksh now (e.g.
  'enum' depends on much of it) so it makes no sense to disable it.
  This was removed in the ksh 93v- beta version as well.
- Remove nv_close() calls and remove nv_close() documentation from
  the nval.3 man page. This function is a dummy, present without
  any changes since the beginning of the ast-open-archive repo in
  1995. The comment was: "Currently this is a dummy, but someday
  will be needed for reference counting". 27 or more years later,
  it's time to admit it's never going to happen. (And of course,
  nv_close() calls were not being used with anything resembling
  consistency.)
- Add a null nv_close() macro to nval.h for compatibility with
  third party code that follows the old documentation.
- Add a few missing regression tests.
This commit is contained in:
Martijn Dekker 2022-02-10 13:44:43 +00:00
parent a00fe6b7fd
commit 14a43a0a88
38 changed files with 101 additions and 356 deletions

View file

@ -124,8 +124,6 @@ The options have the following defaults and meanings:
OPTIMIZE on Optimize loop invariants for with for and while loops. OPTIMIZE on Optimize loop invariants for with for and while loops.
PFSH off Compile with support for profile shell. (Solaris; obsolete)
P_SUID off If set, all real UIDs, greater than or equal to this P_SUID off If set, all real UIDs, greater than or equal to this
value will require the -p flag to run SUID/SGID scripts. value will require the -p flag to run SUID/SGID scripts.
@ -156,8 +154,6 @@ The options have the following defaults and meanings:
exiting the shell when you don't enter a command. If exiting the shell when you don't enter a command. If
non-zero, TMOUT can not be set larger than this value. non-zero, TMOUT can not be set larger than this value.
TYPEDEF on Enable typeset type definitions.
VSH on Compile with vi command line editing. The original vi VSH on Compile with vi command line editing. The original vi
line editor code was provided by Pat Sullivan at CB. line editor code was provided by Pat Sullivan at CB.

View file

@ -30,7 +30,6 @@ SHOPT NAMESPACE=1 # allow namespaces
SHOPT NOECHOE=0 # turn off 'echo -e' when SHOPT_ECHOPRINT is disabled SHOPT NOECHOE=0 # turn off 'echo -e' when SHOPT_ECHOPRINT is disabled
SHOPT OLDTERMIO= # support both TCGETA and TCGETS SHOPT OLDTERMIO= # support both TCGETA and TCGETS
SHOPT OPTIMIZE=1 # optimize loop invariants SHOPT OPTIMIZE=1 # optimize loop invariants
SHOPT PFSH=0 # Solaris exec_attr(4) profile execution (obsolete)
SHOPT P_SUID= # real UIDs that require -p for set[ug]id (do not set to 0 to turn off) SHOPT P_SUID= # real UIDs that require -p for set[ug]id (do not set to 0 to turn off)
SHOPT RAWONLY=1 # make viraw the only vi mode SHOPT RAWONLY=1 # make viraw the only vi mode
SHOPT REGRESS= # enable __regress__ builtin and instrumented intercepts for testing SHOPT REGRESS= # enable __regress__ builtin and instrumented intercepts for testing
@ -41,5 +40,4 @@ SHOPT SUID_EXEC=1 # allow (safe) SUID/SGID shell scripts
SHOPT SYSRC= # attempt . /etc/ksh.kshrc if interactive SHOPT SYSRC= # attempt . /etc/ksh.kshrc if interactive
SHOPT TEST_L= # add 'test -l' as an alias for 'test -L' SHOPT TEST_L= # add 'test -l' as an alias for 'test -L'
SHOPT TIMEOUT= # number of seconds for shell timeout SHOPT TIMEOUT= # number of seconds for shell timeout
SHOPT TYPEDEF=1 # enable typeset type definitions
SHOPT VSH=1 # vi edit mode SHOPT VSH=1 # vi edit mode

View file

@ -153,10 +153,7 @@ void sh_timetraps(void)
sh_fun(tp->action,tp->node,(char**)0); sh_fun(tp->action,tp->node,(char**)0);
tp->flags &= ~L_FLAG; tp->flags &= ~L_FLAG;
if(!tp->flags) if(!tp->flags)
{
nv_unset(tp->node); nv_unset(tp->node);
nv_close(tp->node);
}
} }
} }
if(!(sh.sigflag[SIGALRM]&SH_SIGALRM)) if(!(sh.sigflag[SIGALRM]&SH_SIGALRM))
@ -221,8 +218,6 @@ static void putval(Namval_t* np, const char* val, int flag, Namfun_t* fp)
{ {
tp = (struct tevent*)nv_stack(np, (Namfun_t*)0); tp = (struct tevent*)nv_stack(np, (Namfun_t*)0);
sh.st.timetrap = time_delete(tp,sh.st.timetrap); sh.st.timetrap = time_delete(tp,sh.st.timetrap);
if(tp->action)
nv_close(tp->action);
nv_unset(np); nv_unset(np);
free((void*)fp); free((void*)fp);
} }

View file

@ -180,7 +180,6 @@ int b_getopts(int argc,char *argv[],Shbltin_t *context)
sh.st.optindex = opt_info.index; sh.st.optindex = opt_info.index;
sh.st.optchar = opt_info.offset; sh.st.optchar = opt_info.offset;
nv_putval(np, options, 0); nv_putval(np, options, 0);
nv_close(np);
np = nv_open(nv_name(OPTARGNOD),sh.var_tree,0); np = nv_open(nv_name(OPTARGNOD),sh.var_tree,0);
if(opt_info.num == LONG_MIN) if(opt_info.num == LONG_MIN)
nv_putval(np, opt_info.arg, NV_RDONLY); nv_putval(np, opt_info.arg, NV_RDONLY);
@ -198,7 +197,6 @@ int b_getopts(int argc,char *argv[],Shbltin_t *context)
} }
else else
nv_putval(np, opt_info.arg, NV_RDONLY); nv_putval(np, opt_info.arg, NV_RDONLY);
nv_close(np);
sh_popcontext(&buff); sh_popcontext(&buff);
opt_info.disc = 0; opt_info.disc = 0;
return(r); return(r);

View file

@ -809,7 +809,6 @@ static int extend(Sfio_t* sp, void* v, Sffmt_t* fe)
int32_t sl = 1; int32_t sl = 1;
value->ip = (int*)(((char*)np->nvalue.lp) + (*((char*)&sl) ? 0 : sizeof(int))); value->ip = (int*)(((char*)np->nvalue.lp) + (*((char*)&sl) ? 0 : sizeof(int)));
} }
nv_close(np);
break; break;
} }
case 'q': case 'q':

View file

@ -803,7 +803,6 @@ int sh_readline(char **names, volatile int fd, int flags, ssize_t size, long tim
{ {
if(name) if(name)
{ {
nv_close(np);
np = nv_open(name,sh.var_tree,NV_NOASSIGN|NV_VARNAME); np = nv_open(name,sh.var_tree,NV_NOASSIGN|NV_VARNAME);
name = *++names; name = *++names;
} }
@ -829,7 +828,6 @@ done:
sfset(iop,SF_WRITE,1); sfset(iop,SF_WRITE,1);
if(!was_share) if(!was_share)
sfset(iop,SF_SHARE,0); sfset(iop,SF_SHARE,0);
nv_close(np);
if((sh.fdstatus[fd]&IOTTY) && !keytrap) if((sh.fdstatus[fd]&IOTTY) && !keytrap)
tty_cooked(fd); tty_cooked(fd);
if(flags&S_FLAG) if(flags&S_FLAG)

View file

@ -393,14 +393,12 @@ int b_typeset(int argc,register char *argv[],Shbltin_t *context)
case 'r': case 'r':
flag |= NV_RDONLY; flag |= NV_RDONLY;
break; break;
#if SHOPT_TYPEDEF
case 'S': case 'S':
sflag=1; sflag=1;
break; break;
case 'h': case 'h':
tdata.help = opt_info.arg; tdata.help = opt_info.arg;
break; break;
#endif /* SHOPT_TYPEDEF */
case 's': case 's':
if(!isfloat) if(!isfloat)
{ {
@ -851,7 +849,6 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
if(flag&NV_MOVE) if(flag&NV_MOVE)
{ {
nv_rename(np, flag); nv_rename(np, flag);
nv_close(np);
continue; continue;
} }
if(tp->tp && nv_type(np)!=tp->tp) if(tp->tp && nv_type(np)!=tp->tp)
@ -960,7 +957,6 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
else else
nv_unref(np); nv_unref(np);
} }
nv_close(np);
} }
} }
else else
@ -1142,13 +1138,6 @@ int b_builtin(int argc,char *argv[],Shbltin_t *context)
errormsg(SH_DICT,ERROR_exit(1),e_restricted,argv[-opt_info.index]); errormsg(SH_DICT,ERROR_exit(1),e_restricted,argv[-opt_info.index]);
UNREACHABLE(); UNREACHABLE();
} }
#if SHOPT_PFSH
if(sh_isoption(SH_PFSH))
{
errormsg(SH_DICT,ERROR_exit(1),e_pfsh,argv[-opt_info.index]);
UNREACHABLE();
}
#endif
if(sh.subshell && !sh.subshare) if(sh.subshell && !sh.subshare)
sh_subfork(); sh_subfork();
} }
@ -1403,8 +1392,6 @@ static int unall(int argc, char **argv, register Dt_t *troot)
sh_subfork(); /* avoid affecting the parent shell's alias table */ sh_subfork(); /* avoid affecting the parent shell's alias table */
nv_delete(np,troot,nofree_attr); nv_delete(np,troot,nofree_attr);
} }
else
nv_close(np);
} }
else if(troot==sh.alias_tree) else if(troot==sh.alias_tree)
@ -1532,11 +1519,7 @@ static int print_namval(Sfio_t *file,register Namval_t *np,register int flag, st
sfprintf(file,"[%s]\n", sh_fmtq(nv_refsub(np))); sfprintf(file,"[%s]\n", sh_fmtq(nv_refsub(np)));
} }
else else
#if SHOPT_TYPEDEF
sfputr(file,nv_isvtree(np)?cp:sh_fmtq(cp),'\n'); sfputr(file,nv_isvtree(np)?cp:sh_fmtq(cp),'\n');
#else
sfputr(file,sh_fmtq(cp),'\n');
#endif /* SHOPT_TYPEDEF */
} }
return(1); return(1);
} }
@ -1581,10 +1564,8 @@ static void print_scan(Sfio_t *file, int flag, Dt_t *root, int option,struct tda
tp->scanmask = flag&~NV_NOSCOPE; tp->scanmask = flag&~NV_NOSCOPE;
tp->scanroot = root; tp->scanroot = root;
tp->outfile = file; tp->outfile = file;
#if SHOPT_TYPEDEF
if(!tp->prefix && tp->tp) if(!tp->prefix && tp->tp)
tp->prefix = nv_name(tp->tp); tp->prefix = nv_name(tp->tp);
#endif /* SHOPT_TYPEDEF */
if(flag&NV_INTEGER) if(flag&NV_INTEGER)
tp->scanmask |= (NV_DOUBLE|NV_EXPNOTE); tp->scanmask |= (NV_DOUBLE|NV_EXPNOTE);
if(flag==NV_LTOU || flag==NV_UTOL) if(flag==NV_LTOU || flag==NV_UTOL)

View file

@ -1595,9 +1595,6 @@ const char sh_optksh[] =
#endif #endif
"\b${ENV-$HOME/.kshrc}\b, if it exists, as a profile. " "\b${ENV-$HOME/.kshrc}\b, if it exists, as a profile. "
"On by default for interactive shells; use \b+E\b to disable.]" "On by default for interactive shells; use \b+E\b to disable.]"
#if SHOPT_PFSH
"[P?Invoke the shell as a profile shell. See \bpfexec\b(1).]"
#endif
#if SHOPT_KIA #if SHOPT_KIA
"[R]:[file?Do not execute the script, but create a cross-reference database " "[R]:[file?Do not execute the script, but create a cross-reference database "
"in \afile\a that can be used in a separate shell script browser. The " "in \afile\a that can be used in a separate shell script browser. The "
@ -1885,8 +1882,6 @@ const char sh_opttypeset[] =
"[X]#?[n:=2*sizeof(long long)?Floating point number represented in hexadecimal " "[X]#?[n:=2*sizeof(long long)?Floating point number represented in hexadecimal "
"notation. \an\a specifies the number of significant figures when the " "notation. \an\a specifies the number of significant figures when the "
"value is expanded.]" "value is expanded.]"
#if SHOPT_TYPEDEF
"[h]:[string?Used within a type definition to provide a help string " "[h]:[string?Used within a type definition to provide a help string "
"for variable \aname\a. Otherwise, it is ignored.]" "for variable \aname\a. Otherwise, it is ignored.]"
"[S?Used with a type definition to indicate that the variable is shared by " "[S?Used with a type definition to indicate that the variable is shared by "
@ -1894,7 +1889,6 @@ const char sh_opttypeset[] =
"with the \bfunction\b reserved word, the specified variables " "with the \bfunction\b reserved word, the specified variables "
"will have function static scope. Otherwise, the variable is " "will have function static scope. Otherwise, the variable is "
"unset prior to processing the assignment list.]" "unset prior to processing the assignment list.]"
#endif
"[T]:?[tname?\atname\a is the name of a type name given to each \aname\a.]" "[T]:?[tname?\atname\a is the name of a type name given to each \aname\a.]"
"[Z]#?[n?Zero fill. If \an\a is given it represents the field width.]" "[Z]#?[n?Zero fill. If \an\a is given it represents the field width.]"
"\n" "\n"

View file

@ -2,7 +2,7 @@
* * * *
* This software is part of the ast package * * This software is part of the ast package *
* Copyright (c) 1982-2011 AT&T Intellectual Property * * Copyright (c) 1982-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2021 Contributors to ksh 93u+m * * Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the * * and is licensed under the *
* Eclipse Public License, Version 1.0 * * Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property * * by AT&T Intellectual Property *
@ -242,11 +242,7 @@ static const char sh_lexstate6[256] =
S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG,
S_DIG, S_DIG, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_SPC2, S_DIG, S_DIG, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_SPC2,
#if SHOPT_TYPEDEF
S_SPC1, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_SPC1, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP,
#else
S_SPC2, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP,
#endif
S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP,
S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP, S_ALP,
S_ALP, S_ALP, S_ALP, S_ERR, S_ERR, S_ERR, S_ERR, S_ALP, S_ALP, S_ALP, S_ALP, S_ERR, S_ERR, S_ERR, S_ERR, S_ALP,

View file

@ -67,9 +67,6 @@ const char e_subst[] = "%s: bad substitution";
const char e_create[] = "%s: cannot create"; const char e_create[] = "%s: cannot create";
const char e_tmpcreate[] = "cannot create temporary file"; const char e_tmpcreate[] = "cannot create temporary file";
const char e_restricted[] = "%s: restricted"; const char e_restricted[] = "%s: restricted";
#if SHOPT_PFSH
const char e_pfsh[] = "%s: disabled in profile shell";
#endif
const char e_copexists[] = "coprocess is running; cannot create a new coprocess"; const char e_copexists[] = "coprocess is running; cannot create a new coprocess";
const char e_exists[] = "%s: file already exists"; const char e_exists[] = "%s: file already exists";
const char e_pipe[] = "cannot create pipe"; const char e_pipe[] = "cannot create pipe";

View file

@ -72,9 +72,6 @@ const Shtable_t shtab_options[] =
"pipefail", SH_PIPEFAIL, "pipefail", SH_PIPEFAIL,
"posix", SH_POSIX, "posix", SH_POSIX,
"privileged", SH_PRIVILEGED, "privileged", SH_PRIVILEGED,
#if SHOPT_PFSH
"profile", SH_PFSH|SH_COMMANDLINE,
#endif
"rc", SH_RC|SH_COMMANDLINE, "rc", SH_RC|SH_COMMANDLINE,
"restricted", SH_RESTRICTED, "restricted", SH_RESTRICTED,
"showme", SH_SHOWME, "showme", SH_SHOWME,

View file

@ -34,10 +34,6 @@ tst note{ SHOPT_* option probe }end cross{
*1*) option MULTIBYTE 0 ;; *1*) option MULTIBYTE 0 ;;
esac esac
# deprecated: Solaris disabled SHOPT_PFSH in its build
#test -x /bin/pfexec -o -x /usr/bin/pfexec
#option PFSH $?
# if external 'test' supports lowercase -l as equivalent to -L, enable # if external 'test' supports lowercase -l as equivalent to -L, enable
# SHOPT_TEST_L so ksh supports it for compatibility with local scripts # SHOPT_TEST_L so ksh supports it for compatibility with local scripts
ln -s /dev/null "$EXECROOT/link$$" ln -s /dev/null "$EXECROOT/link$$"

View file

@ -107,10 +107,6 @@ extern char* sh_setenviron(const char*);
# define PIPE_BUF 512 # define PIPE_BUF 512
#endif #endif
#if SHOPT_PFSH && ( !_lib_getexecuser || !_lib_free_execattr )
# undef SHOPT_PFSH
#endif
#define MATCH_MAX 64 #define MATCH_MAX 64
#define SH_READEVAL 0x4000 /* for sh_eval */ #define SH_READEVAL 0x4000 /* for sh_eval */

View file

@ -207,6 +207,7 @@ struct Namval
#define nv_onattr(n,f) ((n)->nvflag |= (f)) #define nv_onattr(n,f) ((n)->nvflag |= (f))
#define nv_offattr(n,f) ((n)->nvflag &= ~(f)) #define nv_offattr(n,f) ((n)->nvflag &= ~(f))
#define nv_isarray(np) (nv_isattr((np),NV_ARRAY)) #define nv_isarray(np) (nv_isattr((np),NV_ARRAY))
#define nv_close(np) /* no-op */
/* The following are operations for associative arrays */ /* The following are operations for associative arrays */
#define NV_AINIT 1 /* initialize */ #define NV_AINIT 1 /* initialize */
@ -252,7 +253,6 @@ extern Namval_t *nv_opensub(Namval_t*);
/* name-value pair function prototypes */ /* name-value pair function prototypes */
extern int nv_adddisc(Namval_t*, const char**, Namval_t**); extern int nv_adddisc(Namval_t*, const char**, Namval_t**);
extern int nv_clone(Namval_t*, Namval_t*, int); extern int nv_clone(Namval_t*, Namval_t*, int);
extern void nv_close(Namval_t*);
extern void *nv_context(Namval_t*); extern void *nv_context(Namval_t*);
extern Namval_t *nv_create(const char*, Dt_t*, int,Namfun_t*); extern Namval_t *nv_create(const char*, Dt_t*, int,Namfun_t*);
extern void nv_delete(Namval_t*, Dt_t*, int); extern void nv_delete(Namval_t*, Dt_t*, int);

View file

@ -97,9 +97,6 @@ extern int path_complete(const char*, const char*,struct argnod**);
#if SHOPT_BRACEPAT #if SHOPT_BRACEPAT
extern int path_generate(struct argnod*,struct argnod**); extern int path_generate(struct argnod*,struct argnod**);
#endif /* SHOPT_BRACEPAT */ #endif /* SHOPT_BRACEPAT */
#if SHOPT_PFSH
extern int path_xattr(const char*, char*);
#endif /* SHOPT_PFSH */
#if SHOPT_DYNAMIC #if SHOPT_DYNAMIC
/* builtin/plugin routines */ /* builtin/plugin routines */
@ -112,9 +109,6 @@ extern const char e_timeformat[];
extern const char e_badtformat[]; extern const char e_badtformat[];
extern const char e_dot[]; extern const char e_dot[];
extern const char e_funload[]; extern const char e_funload[];
#if SHOPT_PFSH
extern const char e_pfsh[];
#endif
extern const char e_pwd[]; extern const char e_pwd[];
extern const char e_logout[]; extern const char e_logout[];
extern const char e_alphanum[]; extern const char e_alphanum[];

View file

@ -99,9 +99,6 @@ typedef union Shnode_u Shnode_t;
#define SH_NOUNSET 9 #define SH_NOUNSET 9
#define SH_NOGLOB 10 #define SH_NOGLOB 10
#define SH_ALLEXPORT 11 #define SH_ALLEXPORT 11
#if SHOPT_PFSH
#define SH_PFSH 12
#endif
#define SH_IGNOREEOF 13 #define SH_IGNOREEOF 13
#define SH_NOCLOBBER 14 #define SH_NOCLOBBER 14
#define SH_MARKDIRS 15 #define SH_MARKDIRS 15

View file

@ -26,7 +26,6 @@ Namdisc_t;
Namval_t *nv_open(const char *\fIname\fP, Dt_t *\fIdict\fP, int \fIflags\fP); Namval_t *nv_open(const char *\fIname\fP, Dt_t *\fIdict\fP, int \fIflags\fP);
Namval_t *nv_create(const char *\fIname\fP, Dt_t *\fIdict\fP, int \fIflags\fP, Namfun_t *\fIfp\fP); Namval_t *nv_create(const char *\fIname\fP, Dt_t *\fIdict\fP, int \fIflags\fP, Namfun_t *\fIfp\fP);
Namval_t *nv_namptr(void *\fIptr\fP, int \fIindx\fP); Namval_t *nv_namptr(void *\fIptr\fP, int \fIindx\fP);
void nv_close(Namval_t *\fInp\fP);
void nv_delete(Namval_t *\fInp\fP, Dt_t *\fIdict\fP, int \fInofree\fP); void nv_delete(Namval_t *\fInp\fP, Dt_t *\fIdict\fP, int \fInofree\fP);
.ft R .ft R
.fi .fi
@ -196,11 +195,6 @@ The \f3nv_namptr\fP function can be used on the pointer returned by
corresponding node. corresponding node.
Each of these nodes must be given the \f3NV_MINIMAL\fP attributes. Each of these nodes must be given the \f3NV_MINIMAL\fP attributes.
.PP .PP
The \f3nv_close()\fP indicates that the pointer returned by
\f3nv_open()\fP or \f3nv_opensub()\fP will not be referenced again. If the
name-value pair is unset, and not referenced elsewhere,
the name-value pair may be freed.
.PP
The \f3nv_delete()\fP function will remove the node \fInp\fP from The \f3nv_delete()\fP function will remove the node \fInp\fP from
the dictionary \fIdict\fP. Unless \fInofree\fP is non-zero, the the dictionary \fIdict\fP. Unless \fInofree\fP is non-zero, the
node \fInp\fP will also be freed. node \fInp\fP will also be freed.
@ -613,8 +607,6 @@ returns \f3NULL\fP.
The \f3nv_opensub()\fP function returns The \f3nv_opensub()\fP function returns
a pointer to the name-value pair corresponding a pointer to the name-value pair corresponding
to the current subscript in an associative array. to the current subscript in an associative array.
Note that the \f3nv_close()\fP function should be called
when the pointer is no longer needed.
.PP .PP
The \f3nv_putsub()\fP function is used to The \f3nv_putsub()\fP function is used to
set the subscript for the next reference to \f3np\fP. set the subscript for the next reference to \f3np\fP.

View file

@ -1697,8 +1697,8 @@ element stores the
submatch. submatch.
For For
.B // .B //
the array is two dimensional with the first subscript indicating the the array is two-dimensional, with the first subscript indicating the
most recent match and subpattern match and the second script indicating most recent match and subpattern match, and the second subscript indicating
which match with which match with
.B 0 .B 0
representing the first match. representing the first match.
@ -2498,7 +2498,7 @@ that directory.
If no file name is found that matches the pattern, then If no file name is found that matches the pattern, then
that component of the filename is left unchanged unless that component of the filename is left unchanged unless
the pattern is prefixed with the pattern is prefixed with
.B \(ap(N)\fP .BR \(ap(N)\fP ,
in which case it is removed as described below. in which case it is removed as described below.
The special traversal names The special traversal names
.B . .B .
@ -2525,8 +2525,7 @@ will be ignored unless the first character of the pattern
corresponding to this component is the character corresponding to this component is the character
.BR . .BR .
itself. itself.
Note, that for other Note that, for uses of pattern matching other than pathname expansion, the
uses of pattern matching the
.B / .B /
and and
.B . .B .
@ -2541,7 +2540,7 @@ When used for filename expansion,
if the if the
.B globstar .B globstar
option is on, an isolated pattern of two adjacent option is on, an isolated pattern of two adjacent
.BR * 's .BR * s
will match all files and zero or more directories will match all files and zero or more directories
and subdirectories. and subdirectories.
If followed by a If followed by a
@ -2562,7 +2561,7 @@ If the first character following the opening
is a is a
.B ! .B !
or or
.B ^ .BR ^ ,
then any character not enclosed is matched. then any character not enclosed is matched.
A A
.B \- .B \-
@ -2574,9 +2573,9 @@ Within
and and
.BR \*(CK\^ , .BR \*(CK\^ ,
character classes can be specified with the syntax character classes can be specified with the syntax
\f3[:\fP\f2class\fP\f3:]\fP \f3[:\fP\f2class\fP\f3:]\fP,
where class is one of the following classes defined in the ANSI C standard: where \f2class\fP is one of the following classes defined in the ANSI C standard
(Note that \f3word\fP is equivalent to \f3alnum\fP plus the character \f3_\fP.) (note that \f3word\fP is equivalent to \f3alnum\fP plus the character \f3_\fP):
.br .br
.B .B
.if n alnum alpha blank cntrl digit graph lower print punct space upper word xdigit .if n alnum alpha blank cntrl digit graph lower print punct space upper word xdigit
@ -2599,6 +2598,7 @@ and
matches the collating symbol \f2symbol\fP. matches the collating symbol \f2symbol\fP.
.RE .RE
.PD .PD
.PP
A A
.I pattern-list .I pattern-list
is a list of one or more patterns separated from each other is a list of one or more patterns separated from each other
@ -2630,7 +2630,7 @@ Matches \f2n\^\fP occurrences of the given patterns.
\f3{\fP\f2m\^\fP\f3,\fP\f2n\^\fP\f3}\fP(\fP\f2pattern-list\^\fP\f3)\fP \f3{\fP\f2m\^\fP\f3,\fP\f2n\^\fP\f3}\fP(\fP\f2pattern-list\^\fP\f3)\fP
Matches from \f2m\^\fP to \f2n\^\fP occurrences of the given patterns. Matches from \f2m\^\fP to \f2n\^\fP occurrences of the given patterns.
If \f2m\^\fP is omitted, \f30\fP will be used. If \f2n\^\fP If \f2m\^\fP is omitted, \f30\fP will be used. If \f2n\^\fP
is omitted at least \f2m\^\fP occurrences will be matched. is omitted, at least \f2m\^\fP occurrences will be matched.
.TP .TP
\f3\&@\&(\fP\f2pattern-list\^\fP\f3)\fP \f3\&@\&(\fP\f2pattern-list\^\fP\f3)\fP
Matches exactly one of the given patterns. Matches exactly one of the given patterns.
@ -2640,19 +2640,19 @@ Matches exactly one of the given patterns.
Matches anything except one of the given patterns. Matches anything except one of the given patterns.
.PD .PD
.RE .RE
By default, each pattern, or subpattern will match the By default, each pattern or subpattern will match the
longest string possible consistent with generating longest string possible consistent with generating
the longest overall match. If more than one match is the longest overall match. If more than one match is
possible, the one starting closest to the beginning possible, the one starting closest to the beginning
of the string will be chosen. However, for each of the above of the string will be chosen. However, for each of the above
compound patterns a \f3\-\fP can be inserted in front of the \f3(\fP compound patterns, a \f3\-\fP can be inserted in front of the \f3(\fP
to cause the shortest match to the specified \f2pattern-list\^\fP to cause the shortest match to the specified \f2pattern-list\^\fP
to be used. to be used.
.PP .PP
When \f2pattern-list\^\fP is contained within parentheses, When \f2pattern-list\^\fP is contained within parentheses,
the backslash character \f3\e\fP is treated specially even the backslash character \f3\e\fP is treated specially even
when inside a character class. All ANSI C character escapes are when inside a character class. All ANSI C character escapes are
recognized and match the specified character. In addition recognized and match the specified character. In addition,
the following escape sequences are recognized: the following escape sequences are recognized:
.PD 0 .PD 0
.RS .RS
@ -2683,7 +2683,7 @@ is a subpattern that
can be used to match nested character expressions. can be used to match nested character expressions.
Each Each
.I pattern-pair\^ .I pattern-pair\^
is a two character sequence which cannot contain is a two-character sequence that cannot contain
.B & .B &
or or
.BR | . .BR | .
@ -2696,7 +2696,7 @@ represents the beginning and ending characters of a nested group that
will be skipped over when counting starting and ending character matches. will be skipped over when counting starting and ending character matches.
The behavior is unspecified when the first character of a The behavior is unspecified when the first character of a
.I pattern-pair\^ .I pattern-pair\^
is alphanumeric is alphanumeric,
except for the following: except for the following:
.PD 0 .PD 0
.RS .RS
@ -2709,11 +2709,11 @@ finding a match.
Causes the ending character to be interpreted as an escape character. Causes the ending character to be interpreted as an escape character.
.TP .TP
.B L .B L
Causes the ending character to be interpreted as a quote character Causes the ending character to be interpreted as a quote character,
causing all characters to be ignored when looking for a match. causing all characters to be ignored when looking for a match.
.TP .TP
.B Q .B Q
Causes the ending character to be interpreted as a quote character Causes the ending character to be interpreted as a quote character,
causing all characters other than any escape character to be ignored causing all characters other than any escape character to be ignored
when looking for a match. when looking for a match.
.PD .PD
@ -2724,14 +2724,14 @@ matches characters starting at
.B { .B {
until the matching until the matching
.B } .B }
is found not counting any is found, not counting any
.B { .B {
or or
.B } .B }
that is inside a double quoted string or preceded by the escape character that is inside a double-quoted string or preceded by the escape character
.BR \e . .BR \e .
Without the Without the
.B {\^} .BR {\^} ,
this pattern matches any C language string. this pattern matches any C language string.
.PP .PP
Each subpattern in a composite pattern is numbered, Each subpattern in a composite pattern is numbered,
@ -2739,10 +2739,10 @@ starting at 1, by the location of the \f3(\fP within
the pattern. the pattern.
The sequence \f3\e\fP\f2n\^\fP, where \f2n\^\fP The sequence \f3\e\fP\f2n\^\fP, where \f2n\^\fP
is a single digit and \f3\e\fP\f2n\^\fP comes after is a single digit and \f3\e\fP\f2n\^\fP comes after
the \f2n\fP-th. subpattern, the \f2n\fPth subpattern,
matches the same string as the subpattern itself. matches the same string as the subpattern itself.
.PP .PP
Finally a pattern can contain subpatterns of the form Finally, a pattern can contain subpatterns of the form
\f3\(ap(\fP\f2options\^\fP\f3:\fP\f2pattern-list\^\fP\f3)\fP, \f3\(ap(\fP\f2options\^\fP\f3:\fP\f2pattern-list\^\fP\f3)\fP,
where either \f2options\^\fP or \f3:\fP\f2pattern-list\^\fP where either \f2options\^\fP or \f3:\fP\f2pattern-list\^\fP
can be omitted. Unlike the other compound patterns, can be omitted. Unlike the other compound patterns,
@ -2750,7 +2750,7 @@ these subpatterns are not counted in the numbered subpatterns.
\f3:\fP\f2pattern-list\^\fP must be omitted for options \f3:\fP\f2pattern-list\^\fP must be omitted for options
.BR F , .BR F ,
.BR G , .BR G ,
.B N , .BR N ,
and and
.B V .B V
below. below.
@ -2768,33 +2768,41 @@ Disable the following options.
.B E .B E
The remainder of the pattern uses extended regular expression syntax The remainder of the pattern uses extended regular expression syntax
like the like the
.IR egrep (1) .B \-E
option of the
.IR grep (1)
command. command.
.TP .TP
.B F .B F
The remainder of the pattern uses The remainder of the pattern uses the fixed pattern syntax of the
.IR fgrep (1) .B \-F
expression syntax. option of the
.IR grep (1)
command.
.TP .TP
.B G .B G
The remainder of the pattern uses basic regular expression syntax The remainder of the pattern uses basic regular expression syntax
like the like the
.IR grep (1) .IR grep (1)
command. command without options.
.TP .TP
.B K .B K
The remainder of the pattern uses shell pattern syntax. The remainder of the pattern uses shell pattern syntax.
This is the default. This is the default.
.TP .TP
.B N .B N
This is ignored. However, when it is the first letter and is When it is the first letter and is
used with pathname expansion, and no matches occur, used with pathname expansion, and no matches occur,
the file pattern expands to the empty string. the file pattern expands to the empty string
instead of remaining unexpanded.
Otherwise, it is ignored.
.TP .TP
.B X .B X
The remainder of the pattern uses augmented regular expression syntax The remainder of the pattern uses augmented regular expression syntax
like the like the
.IR xgrep (1) .B \-X
option of the AT&T AST version of the
.IR grep (1)
command. command.
.TP .TP
.B P .B P
@ -2815,12 +2823,12 @@ shell option.
File the longest match (greedy). This is the default. File the longest match (greedy). This is the default.
.TP .TP
.B l .B l
Left anchor the pattern. This is the default for Left-anchor the pattern. This is the default for
.B K .B K
style patterns. style patterns.
.TP .TP
.B r .B r
Right anchor the pattern. This is the default for Right-anchor the pattern. This is the default for
.B K .B K
style patterns. style patterns.
.PD .PD

View file

@ -48,9 +48,6 @@ static char *null;
/* The following order is determined by sh_optset */ /* The following order is determined by sh_optset */
static const char optksh[] = static const char optksh[] =
#if SHOPT_PFSH
"P"
#endif
"Dircabefhkmnpstuvx" "Dircabefhkmnpstuvx"
#if SHOPT_BRACEPAT #if SHOPT_BRACEPAT
"B" "B"
@ -62,9 +59,6 @@ static const char optksh[] =
; ;
static const int flagval[] = static const int flagval[] =
{ {
#if SHOPT_PFSH
SH_PFSH,
#endif
SH_DICTIONARY, SH_INTERACTIVE, SH_RESTRICTED, SH_CFLAG, SH_DICTIONARY, SH_INTERACTIVE, SH_RESTRICTED, SH_CFLAG,
SH_ALLEXPORT, SH_NOTIFY, SH_ERREXIT, SH_NOGLOB, SH_TRACKALL, SH_ALLEXPORT, SH_NOTIFY, SH_ERREXIT, SH_NOGLOB, SH_TRACKALL,
SH_KEYWORD, SH_MONITOR, SH_NOEXEC, SH_PRIVILEGED, SH_SFLAG, SH_TFLAG, SH_KEYWORD, SH_MONITOR, SH_NOEXEC, SH_PRIVILEGED, SH_SFLAG, SH_TFLAG,
@ -306,10 +300,7 @@ int sh_argopts(int argc,register char *argv[])
strsort(sh.st.dolv+1,sh.st.dolc,strcoll); strsort(sh.st.dolv+1,sh.st.dolc,strcoll);
} }
if(np) if(np)
{
nv_setvec(np,0,argc,argv); nv_setvec(np,0,argc,argv);
nv_close(np);
}
else if(argc>0 || ((cp=argv[-1]) && strcmp(cp,"--")==0)) else if(argc>0 || ((cp=argv[-1]) && strcmp(cp,"--")==0))
argset(ap,argv-1); argset(ap,argv-1);
} }

View file

@ -404,7 +404,9 @@ static Namval_t *array_find(Namval_t *np,Namarr_t *arp, int flag)
return(np); return(np);
} }
#if SHOPT_TYPEDEF /*
* for 'typeset -T' types
*/
int nv_arraysettype(Namval_t *np, Namval_t *tp, const char *sub, int flags) int nv_arraysettype(Namval_t *np, Namval_t *tp, const char *sub, int flags)
{ {
Namval_t *nq; Namval_t *nq;
@ -431,7 +433,6 @@ int nv_arraysettype(Namval_t *np, Namval_t *tp, const char *sub, int flags)
} }
return(0); return(0);
} }
#endif /* SHOPT_TYPEDEF */
static Namfun_t *array_clone(Namval_t *np, Namval_t *mp, int flags, Namfun_t *fp) static Namfun_t *array_clone(Namval_t *np, Namval_t *mp, int flags, Namfun_t *fp)
@ -622,10 +623,8 @@ static void array_putval(Namval_t *np, const char *string, int flags, Namfun_t *
nv_putval(mp, string, flags); nv_putval(mp, string, flags);
if(string) if(string)
{ {
#if SHOPT_TYPEDEF
if(ap->hdr.type && ap->hdr.type!=nv_type(mp)) if(ap->hdr.type && ap->hdr.type!=nv_type(mp))
nv_arraysettype(np,ap->hdr.type,nv_getsub(np),0); nv_arraysettype(np,ap->hdr.type,nv_getsub(np),0);
#endif /* SHOPT_TYPEDEF */
continue; continue;
} }
ap->nelem |= scan; ap->nelem |= scan;
@ -713,10 +712,8 @@ static void array_putval(Namval_t *np, const char *string, int flags, Namfun_t *
else if(mp==np) else if(mp==np)
aq->val[aq->cur].cp = 0; aq->val[aq->cur].cp = 0;
} }
#if SHOPT_TYPEDEF
if(string && ap->hdr.type && nv_isvtree(np)) if(string && ap->hdr.type && nv_isvtree(np))
nv_arraysettype(np,ap->hdr.type,nv_getsub(np),0); nv_arraysettype(np,ap->hdr.type,nv_getsub(np),0);
#endif /* SHOPT_TYPEDEF */
} }
while(!string && nv_nextsub(np)); while(!string && nv_nextsub(np));
if(ap) if(ap)

View file

@ -587,9 +587,7 @@ void sh_exit(register int xno)
sh.arithrecursion = 0; sh.arithrecursion = 0;
sh.intrace = 0; sh.intrace = 0;
sh.prefix = 0; sh.prefix = 0;
#if SHOPT_TYPEDEF
sh.mktype = 0; sh.mktype = 0;
#endif /* SHOPT_TYPEDEF */
if(job.in_critical) if(job.in_critical)
job_unlock(); job_unlock();
if(pp->mode == SH_JMPSCRIPT && !pp->prev) if(pp->mode == SH_JMPSCRIPT && !pp->prev)

View file

@ -131,10 +131,6 @@ char e_version[] = "\n@(#)$Id: Version "
#define ATTRS 1 #define ATTRS 1
"M" "M"
#endif #endif
#if SHOPT_PFSH && _hdr_exec_attr
#define ATTRS 1
"P"
#endif
#if SHOPT_REGRESS #if SHOPT_REGRESS
#define ATTRS 1 #define ATTRS 1
"R" "R"
@ -1200,14 +1196,6 @@ int sh_type(register const char *path)
} }
if (!(t & (SH_TYPE_PROFILE|SH_TYPE_RESTRICTED))) if (!(t & (SH_TYPE_PROFILE|SH_TYPE_RESTRICTED)))
{ {
#if SHOPT_PFSH
if (*s == 'p' && *(s+1) == 'f')
{
s += 2;
t |= SH_TYPE_PROFILE;
continue;
}
#endif
if (*s == 'r') if (*s == 'r')
{ {
s++; s++;
@ -1406,11 +1394,6 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit)
/* check for restricted shell */ /* check for restricted shell */
if(type&SH_TYPE_RESTRICTED) if(type&SH_TYPE_RESTRICTED)
sh_onoption(SH_RESTRICTED); sh_onoption(SH_RESTRICTED);
#if SHOPT_PFSH
/* check for profile shell */
else if(type&SH_TYPE_PROFILE)
sh_onoption(SH_PFSH);
#endif
/* look for options */ /* look for options */
/* sh.st.dolc is $# */ /* sh.st.dolc is $# */
if((sh.st.dolc = sh_argopts(-argc,argv)) < 0) if((sh.st.dolc = sh_argopts(-argc,argv)) < 0)
@ -1468,15 +1451,6 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit)
/* import variable attributes from environment */ /* import variable attributes from environment */
if(!sh_isoption(SH_POSIX)) if(!sh_isoption(SH_POSIX))
env_import_attributes(save_envmarker); env_import_attributes(save_envmarker);
#if SHOPT_PFSH
if (sh_isoption(SH_PFSH))
{
struct passwd *pw = getpwuid(sh.userid);
if(pw)
sh.user = sh_strdup(pw->pw_name);
}
#endif
/* set[ug]id scripts require the -p flag */ /* set[ug]id scripts require the -p flag */
if(sh.userid!=sh.euserid || sh.groupid!=sh.egroupid) if(sh.userid!=sh.euserid || sh.groupid!=sh.egroupid)
{ {
@ -2054,7 +2028,6 @@ static char *env_init(void)
{ {
nv_onattr(np,NV_IMPORT); nv_onattr(np,NV_IMPORT);
np->nvenv = cp; np->nvenv = cp;
nv_close(np);
} }
else /* swap with front */ else /* swap with front */
{ {

View file

@ -870,9 +870,7 @@ int sh_lex(Lex_t* lp)
poplevel(lp); poplevel(lp);
} }
break; break;
#if SHOPT_TYPEDEF
case '@': case '@':
#endif /* SHOPT_TYPEDEF */
case '!': case '!':
if(n!=S_ALP) if(n!=S_ALP)
goto dolerr; goto dolerr;

View file

@ -91,7 +91,7 @@ typedef struct _mac_
#define M_NAMECOUNT 7 /* ${#var*} */ #define M_NAMECOUNT 7 /* ${#var*} */
#define M_TYPE 8 /* ${@var} */ #define M_TYPE 8 /* ${@var} */
static noreturn void mac_error(Namval_t*); static noreturn void mac_error(void);
static int substring(const char*, size_t, const char*, int[], int); static int substring(const char*, size_t, const char*, int[], int);
static void copyto(Mac_t*, int, int); static void copyto(Mac_t*, int, int);
static void comsubst(Mac_t*, Shnode_t*, int); static void comsubst(Mac_t*, Shnode_t*, int);
@ -1128,13 +1128,11 @@ retry1:
{ {
if(c=='#') if(c=='#')
type = M_SIZE; type = M_SIZE;
#if SHOPT_TYPEDEF
else if(c=='@') else if(c=='@')
{ {
type = M_TYPE; type = M_TYPE;
goto retry1; goto retry1;
} }
#endif /* SHOPT_TYPEDEF */
else else
type = M_VNAME; type = M_VNAME;
mode = c; mode = c;
@ -1439,7 +1437,6 @@ retry1:
if(ap && !mp->dotdot && !(ap->nelem&ARRAY_UNDEF)) if(ap && !mp->dotdot && !(ap->nelem&ARRAY_UNDEF))
addsub = 1; addsub = 1;
} }
#if SHOPT_TYPEDEF
else if(type==M_TYPE) else if(type==M_TYPE)
{ {
Namval_t *nq = nv_type(np); Namval_t *nq = nv_type(np);
@ -1450,7 +1447,6 @@ retry1:
nv_attribute(np,sh.strbuf,"typeset",1); nv_attribute(np,sh.strbuf,"typeset",1);
v = sfstruse(sh.strbuf); v = sfstruse(sh.strbuf);
} }
#endif /* SHOPT_TYPEDEF */
#if SHOPT_FILESCAN #if SHOPT_FILESCAN
else if(sh.cur_line && np==REPLYNOD) else if(sh.cur_line && np==REPLYNOD)
v = sh.cur_line; v = sh.cur_line;
@ -1521,7 +1517,7 @@ retry1:
if(type>M_TREE) if(type>M_TREE)
{ {
if(c!=RBRACE) if(c!=RBRACE)
mac_error(np); mac_error();
if(type==M_NAMESCAN || type==M_NAMECOUNT) if(type==M_NAMESCAN || type==M_NAMECOUNT)
{ {
sh.last_root = sh.var_tree; sh.last_root = sh.var_tree;
@ -1602,7 +1598,7 @@ retry1:
if(!isbracechar(c)) if(!isbracechar(c))
{ {
if(!nulflg) if(!nulflg)
mac_error(np); mac_error();
fcseek(-LEN); fcseek(-LEN);
c = ':'; c = ':';
} }
@ -1781,7 +1777,7 @@ retry1:
vsize = v?strlen(v):0; vsize = v?strlen(v):0;
} }
if(*ptr) if(*ptr)
mac_error(np); mac_error();
stkseek(stkp,offset); stkseek(stkp,offset);
argp = 0; argp = 0;
} }
@ -2022,7 +2018,7 @@ retry2:
goto retry2; goto retry2;
} }
else else
mac_error(np); mac_error();
} }
} }
else if(var && sh_isoption(SH_NOUNSET) && type<=M_TREE && (!np || nv_isnull(np) || (nv_isarray(np) && !np->nvalue.cp))) else if(var && sh_isoption(SH_NOUNSET) && type<=M_TREE && (!np || nv_isnull(np) || (nv_isarray(np) && !np->nvalue.cp)))
@ -2036,13 +2032,10 @@ retry2:
} }
else else
id = nv_name(np); id = nv_name(np);
nv_close(np);
} }
errormsg(SH_DICT,ERROR_exit(1),e_notset,id); errormsg(SH_DICT,ERROR_exit(1),e_notset,id);
UNREACHABLE(); UNREACHABLE();
} }
if(np)
nv_close(np);
if(pattern) if(pattern)
free(pattern); free(pattern);
if(idx) if(idx)
@ -2056,9 +2049,8 @@ nosub:
return(1); return(1);
} }
if(type) if(type)
mac_error(np); mac_error();
fcseek(-1); fcseek(-1);
nv_close(np);
return(0); return(0);
} }
@ -2798,10 +2790,8 @@ static char *special(register int c)
/* /*
* Handle macro expansion errors * Handle macro expansion errors
*/ */
static noreturn void mac_error(Namval_t *np) static noreturn void mac_error(void)
{ {
if(np)
nv_close(np);
errormsg(SH_DICT,ERROR_exit(1),e_subst,fcfirst()); errormsg(SH_DICT,ERROR_exit(1),e_subst,fcfirst());
UNREACHABLE(); UNREACHABLE();
} }

View file

@ -77,16 +77,15 @@ struct adata
char *attval; char *attval;
}; };
#if SHOPT_TYPEDEF /* for a 'typeset -T' type */
struct sh_type struct sh_type
{ {
void *previous; void *previous;
Namval_t **nodes; Namval_t **nodes;
Namval_t *rp; Namval_t *rp;
short numnodes; short numnodes;
short maxnodes; short maxnodes;
}; };
#endif /* SHOPT_TYPEDEF */
#if NVCACHE #if NVCACHE
struct Namcache struct Namcache
@ -175,7 +174,9 @@ void nv_outname(Sfio_t *out, char *name, int len)
stakseek(offset); stakseek(offset);
} }
#if SHOPT_TYPEDEF /*
* for 'typeset -T' types
*/
Namval_t *nv_addnode(Namval_t* np, int remove) Namval_t *nv_addnode(Namval_t* np, int remove)
{ {
register struct sh_type *sp = (struct sh_type*)sh.mktype; register struct sh_type *sp = (struct sh_type*)sh.mktype;
@ -233,7 +234,6 @@ Namval_t *nv_addnode(Namval_t* np, int remove)
sp->nodes[sp->numnodes++] = np; sp->nodes[sp->numnodes++] = np;
return(np); return(np);
} }
#endif /* SHOPT_TYPEDEF */
/* /*
* given a list of assignments, determine <name> is on the list * given a list of assignments, determine <name> is on the list
@ -271,8 +271,7 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
Namarr_t *ap; Namarr_t *ap;
Namval_t node; Namval_t node;
struct Namref nr; struct Namref nr;
#if SHOPT_TYPEDEF int maketype = flags&NV_TYPE; /* make a 'typeset -T' type definition command */
int maketype = flags&NV_TYPE;
struct sh_type shtp; struct sh_type shtp;
if(maketype) if(maketype)
{ {
@ -283,7 +282,6 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
shtp.rp = 0; shtp.rp = 0;
shtp.nodes = (Namval_t**)sh_malloc(shtp.maxnodes*sizeof(Namval_t*)); shtp.nodes = (Namval_t**)sh_malloc(shtp.maxnodes*sizeof(Namval_t*));
} }
#endif /* SHOPT_TYPEDEF */
#if SHOPT_NAMESPACE #if SHOPT_NAMESPACE
if(sh.namespace && nv_dict(sh.namespace)==sh.var_tree) if(sh.namespace && nv_dict(sh.namespace)==sh.var_tree)
flags |= NV_NOSCOPE; flags |= NV_NOSCOPE;
@ -344,7 +342,6 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
stakputs(cp); stakputs(cp);
cp = stakfreeze(1); cp = stakfreeze(1);
} }
nv_close(np);
} }
} }
np = nv_open(cp,sh.var_tree,flag|NV_ASSIGN); np = nv_open(cp,sh.var_tree,flag|NV_ASSIGN);
@ -378,11 +375,7 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
nv_settype(np,typ,0); nv_settype(np,typ,0);
} }
if((flags&NV_STATIC) && !nv_isattr(np,NV_EXPORT) && !nv_isnull(np)) if((flags&NV_STATIC) && !nv_isattr(np,NV_EXPORT) && !nv_isnull(np))
#if SHOPT_TYPEDEF
goto check_type; goto check_type;
#else
continue;
#endif /* SHOPT_TYPEDEF */
ap=nv_arrayptr(np); ap=nv_arrayptr(np);
#if SHOPT_FIXEDARRAY #if SHOPT_FIXEDARRAY
if(ap && ap->fixed) if(ap && ap->fixed)
@ -408,13 +401,7 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
} }
} }
if(array && tp->tre.tretyp!=TLST && !tp->com.comset && !tp->com.comarg) if(array && tp->tre.tretyp!=TLST && !tp->com.comset && !tp->com.comarg)
{
#if SHOPT_TYPEDEF
goto check_type; goto check_type;
#else
continue;
#endif /* SHOPT_TYPEDEF */
}
/* check for array assignment */ /* check for array assignment */
if(tp->tre.tretyp!=TLST && tp->com.comarg && !tp->com.comset && ((array&NV_IARRAY) || !((mp=tp->com.comnamp) && nv_isattr(mp,BLT_DCL)))) if(tp->tre.tretyp!=TLST && tp->com.comarg && !tp->com.comset && ((array&NV_IARRAY) || !((mp=tp->com.comnamp) && nv_isattr(mp,BLT_DCL))))
{ {
@ -422,14 +409,12 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
Dt_t *last_root = sh.last_root; Dt_t *last_root = sh.last_root;
char **argv = sh_argbuild(&argc,&tp->com,0); char **argv = sh_argbuild(&argc,&tp->com,0);
sh.last_root = last_root; sh.last_root = last_root;
#if SHOPT_TYPEDEF
if(sh.mktype && sh.dot_depth==0 && np==((struct sh_type*)sh.mktype)->nodes[0]) if(sh.mktype && sh.dot_depth==0 && np==((struct sh_type*)sh.mktype)->nodes[0])
{ {
sh.mktype = 0; sh.mktype = 0;
errormsg(SH_DICT,ERROR_exit(1),"%s: not a known type name",argv[0]); errormsg(SH_DICT,ERROR_exit(1),"%s: not a known type name",argv[0]);
UNREACHABLE(); UNREACHABLE();
} }
#endif /* SHOPT_TYPEDEF */
if(!(arg->argflag&ARG_APPEND)) if(!(arg->argflag&ARG_APPEND))
{ {
#if SHOPT_FIXEDARRAY #if SHOPT_FIXEDARRAY
@ -462,11 +447,7 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
sfwrite(sfstderr,")\n",2); sfwrite(sfstderr,")\n",2);
} }
} }
#if SHOPT_TYPEDEF
goto check_type; goto check_type;
#else
continue;
#endif /* SHOPT_TYPEDEF */
} }
if((tp->tre.tretyp&COMMSK)==TFUN) if((tp->tre.tretyp&COMMSK)==TFUN)
goto skip; goto skip;
@ -494,17 +475,11 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
sh.prefix = prefix; sh.prefix = prefix;
if(tp->com.comset->argval[1]!='[') if(tp->com.comset->argval[1]!='[')
nv_setvtree(np); nv_setvtree(np);
nv_close(np);
#if SHOPT_TYPEDEF
goto check_type; goto check_type;
#else
continue;
#endif /* SHOPT_TYPEDEF */
} }
if(*cp!='.' && *cp!='[' && strchr(cp,'[')) if(*cp!='.' && *cp!='[' && strchr(cp,'['))
{ {
cp = stakcopy(nv_name(np)); cp = stakcopy(nv_name(np));
nv_close(np);
if(!(arg->argflag&ARG_APPEND)) if(!(arg->argflag&ARG_APPEND))
flag &= ~NV_ARRAY; flag &= ~NV_ARRAY;
sh.prefix_root = sh.first_root; sh.prefix_root = sh.first_root;
@ -570,9 +545,7 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
L_ARGNOD->nvfun = 0; L_ARGNOD->nvfun = 0;
} }
sh_exec(tp,sh_isstate(SH_ERREXIT)); sh_exec(tp,sh_isstate(SH_ERREXIT));
#if SHOPT_TYPEDEF
if(sh.prefix) if(sh.prefix)
#endif
{ {
L_ARGNOD->nvalue.nrp = node.nvalue.nrp; L_ARGNOD->nvalue.nrp = node.nvalue.nrp;
L_ARGNOD->nvflag = node.nvflag; L_ARGNOD->nvflag = node.nvflag;
@ -594,11 +567,7 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
if(tp->com.comarg || tp->com.comset) if(tp->com.comarg || tp->com.comset)
np->nvfun->dsize = 0; np->nvfun->dsize = 0;
} }
#if SHOPT_TYPEDEF
goto check_type; goto check_type;
#else
continue;
#endif /* SHOPT_TYPEDEF */
} }
cp = arg->argval; cp = arg->argval;
mp = 0; mp = 0;
@ -659,7 +628,6 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
sh_debug(trap,name,sub,av,append); sh_debug(trap,name,sub,av,append);
} }
} }
#if SHOPT_TYPEDEF
check_type: check_type:
if(maketype) if(maketype)
{ {
@ -678,7 +646,7 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
L_ARGNOD->nvfun = node.nvfun; L_ARGNOD->nvfun = node.nvfun;
} }
} }
#endif /* SHOPT_TYPEDEF */ /* continue loop */
} }
} }
@ -1490,10 +1458,8 @@ nocache:
} }
c = *cp; c = *cp;
skip: skip:
#if SHOPT_TYPEDEF
if(np && sh.mktype) if(np && sh.mktype)
np = nv_addnode(np,0); np = nv_addnode(np,0);
#endif /* SHOPT_TYPEDEF */
if(c=='=' && np && (flags&NV_ASSIGN)) if(c=='=' && np && (flags&NV_ASSIGN))
{ {
cp++; cp++;
@ -2271,10 +2237,8 @@ static int scanfilter(Namval_t *np, struct scan *sp)
register int k=np->nvflag; register int k=np->nvflag;
register struct adata *tp = (struct adata*)sp->scandata; register struct adata *tp = (struct adata*)sp->scandata;
char *cp; char *cp;
#if SHOPT_TYPEDEF
if(!is_abuiltin(np) && tp && tp->tp && nv_type(np)!=tp->tp) if(!is_abuiltin(np) && tp && tp->tp && nv_type(np)!=tp->tp)
return(0); return(0);
#endif /* SHOPT_TYPEDEF */
if(sp->scanmask==NV_TABLE && nv_isvtree(np)) if(sp->scanmask==NV_TABLE && nv_isvtree(np))
k = NV_TABLE; k = NV_TABLE;
if(sp->scanmask?(k&sp->scanmask)==sp->scanflags:(!sp->scanflags || (k&sp->scanflags))) if(sp->scanmask?(k&sp->scanmask)==sp->scanflags:(!sp->scanflags || (k&sp->scanflags)))
@ -2423,15 +2387,6 @@ void sh_envnolocal (register Namval_t *np, void *data)
nv_onattr(np,NV_EXPORT); nv_onattr(np,NV_EXPORT);
} }
/*
* Currently this is a dummy, but someday will be needed
* for reference counting
*/
void nv_close(Namval_t *np)
{
NOT_USED(np);
}
static void table_unset(register Dt_t *root, int flags, Dt_t *oroot) static void table_unset(register Dt_t *root, int flags, Dt_t *oroot)
{ {
register Namval_t *np,*nq, *npnext; register Namval_t *np,*nq, *npnext;
@ -3030,7 +2985,7 @@ void nv_newattr (register Namval_t *np, unsigned newatts, int size)
np->nvflag |= newatts; np->nvflag |= newatts;
goto skip; goto skip;
} }
#endif /* SHOPT_TYPEDEF */ #endif /* SHOPT_FIXEDARRAY */
} }
do do
{ {
@ -3113,7 +3068,7 @@ void nv_newattr (register Namval_t *np, unsigned newatts, int size)
while(ap && nv_nextsub(np)); while(ap && nv_nextsub(np));
#if SHOPT_FIXEDARRAY #if SHOPT_FIXEDARRAY
skip: skip:
#endif /* SHOPT_TYPEDEF */ #endif /* SHOPT_FIXEDARRAY */
if(fp) if(fp)
np->nvfun = fp; np->nvfun = fp;
if(ap) if(ap)

View file

@ -246,8 +246,7 @@ static void assign(Namval_t *np,const char* val,int flags,Namfun_t *handle)
struct blocked block, *bp = block_info(np, &block); struct blocked block, *bp = block_info(np, &block);
Namval_t node; Namval_t node;
union Value *up = np->nvalue.up; union Value *up = np->nvalue.up;
#if SHOPT_TYPEDEF Namval_t *tp, *nr; /* for 'typeset -T' types */
Namval_t *tp, *nr;
if(val && (tp=nv_type(np)) && (nr=nv_open(val,sh.var_tree,NV_VARNAME|NV_ARRAY|NV_NOADD|NV_NOFAIL)) && tp==nv_type(nr)) if(val && (tp=nv_type(np)) && (nr=nv_open(val,sh.var_tree,NV_VARNAME|NV_ARRAY|NV_NOADD|NV_NOFAIL)) && tp==nv_type(nr))
{ {
char *sub = nv_getsub(np); char *sub = nv_getsub(np);
@ -261,7 +260,6 @@ static void assign(Namval_t *np,const char* val,int flags,Namfun_t *handle)
nv_clone(nr,np,0); nv_clone(nr,np,0);
goto done; goto done;
} }
#endif /* SHOPT_TYPEDEF */
if(val || isblocked(bp,type)) if(val || isblocked(bp,type))
{ {
if(!nq || isblocked(bp,type)) if(!nq || isblocked(bp,type))
@ -1278,7 +1276,6 @@ Namval_t *sh_addbuiltin(const char *path, Shbltin_f bltin, void *extra)
if(nq) if(nq)
{ {
cp=nv_setdisc(nq,cp+1,np,(Namfun_t*)nq); cp=nv_setdisc(nq,cp+1,np,(Namfun_t*)nq);
nv_close(nq);
if(!cp) if(!cp)
{ {
errormsg(SH_DICT,ERROR_exit(1),e_baddisc,name); errormsg(SH_DICT,ERROR_exit(1),e_baddisc,name);

View file

@ -878,7 +878,6 @@ static char **genvalue(char **argv, const char *prefix, int n, struct Walk *wp)
if(wp->indent>0) if(wp->indent>0)
sfnputc(outfile,'\t',wp->indent); sfnputc(outfile,'\t',wp->indent);
nv_attribute(np,outfile,"typeset",1); nv_attribute(np,outfile,"typeset",1);
nv_close(np);
sfputr(outfile,arg+m+r+(n?n:0),(k?'=':'\n')); sfputr(outfile,arg+m+r+(n?n:0),(k?'=':'\n'));
if(!k) if(!k)
{ {

View file

@ -450,10 +450,8 @@ static Namfun_t *clone_type(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp)
} }
else else
nv_putval(nq,nv_getval(nr),NV_RDONLY); nv_putval(nq,nv_getval(nr),NV_RDONLY);
#if SHOPT_TYPEDEF
if(sh.mktype) if(sh.mktype)
nv_addnode(nr,1); nv_addnode(nr,1);
#endif /* SHOPT_TYPEDEF */
if(pp->strsize<0) if(pp->strsize<0)
continue; continue;
_nv_unset(nr,0); _nv_unset(nr,0);
@ -1303,7 +1301,6 @@ int nv_settype(Namval_t* np, Namval_t *tp, int flags)
Namarr_t *ap=0; Namarr_t *ap=0;
int nelem = 0; int nelem = 0;
unsigned int subshell = sh.subshell; unsigned int subshell = sh.subshell;
#if SHOPT_TYPEDEF
Namval_t *tq; Namval_t *tq;
if(nv_type(np)==tp) if(nv_type(np)==tp)
return(0); return(0);
@ -1341,8 +1338,8 @@ int nv_settype(Namval_t* np, Namval_t *tp, int flags)
} }
} }
else else
#endif /* SHOPT_TYPEDEF */
{ {
/* non-typeset -T type */
if(isnull) if(isnull)
flags &= ~NV_APPEND; flags &= ~NV_APPEND;
else if(!nv_isvtree(np)) else if(!nv_isvtree(np))

View file

@ -36,16 +36,6 @@
#include "test.h" #include "test.h"
#include "FEATURE/dynamic" #include "FEATURE/dynamic"
#include "FEATURE/externs" #include "FEATURE/externs"
#if SHOPT_PFSH
# ifdef _hdr_exec_attr
# include <exec_attr.h>
# endif
# if _lib_vfork
# include <ast_vfork.h>
# else
# define vfork() fork()
# endif
#endif
#define RW_ALL (S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH) #define RW_ALL (S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH)
#define LIBCMD "cmd" #define LIBCMD "cmd"
@ -87,60 +77,6 @@ static int ondefpath(const char *name)
return(0); return(0);
} }
#if SHOPT_PFSH
int path_xattr(const char *path, char *rpath)
{
char resolvedpath[PATH_MAX + 1];
if (sh.user && *sh.user)
{
execattr_t *pf;
if(!rpath)
rpath = resolvedpath;
if (!realpath(path, resolvedpath))
return -1;
if(pf=getexecuser(sh.user, KV_COMMAND, resolvedpath, GET_ONE))
{
if (!pf->attr || pf->attr->length == 0)
{
free_execattr(pf);
return(0);
}
free_execattr(pf);
return(1);
}
}
errno = ENOENT;
return(-1);
}
static pid_t pf_execve(const char *path, char *argv[],char *const envp[],int spawn)
{
char resolvedpath[PATH_MAX + 1];
pid_t pid;
if(spawn)
{
while((pid = vfork()) < 0)
_sh_fork(pid, 0, (int*)0);
if(pid)
return(pid);
}
if(!sh_isoption(SH_PFSH))
return(execve(path, argv, envp));
/* Solaris implements realpath(3C) using the resolvepath(2) */
/* system call so we can save us to call access(2) first */
/* we can exec the command directly instead of via pfexec(1) if */
/* there is a matching entry without attributes in exec_attr(4) */
if(!path_xattr(path,resolvedpath))
return(execve(path, argv, envp));
--argv;
argv[0] = argv[1];
argv[1] = resolvedpath;
return(execve("/usr/bin/pfexec", argv, envp));
}
#endif /* SHOPT_PFSH */
static pid_t _spawnveg(const char *path, char* const argv[], char* const envp[], pid_t pgid) static pid_t _spawnveg(const char *path, char* const argv[], char* const envp[], pid_t pgid)
{ {
pid_t pid; pid_t pid;
@ -219,11 +155,7 @@ static pid_t command_xargs(const char *path, char *argv[],char *const envp[], in
saveargs = 0; saveargs = 0;
} }
} }
#if SHOPT_PFSH
else if(spawn && !sh_isoption(SH_PFSH))
#else
else if(spawn) else if(spawn)
#endif
{ {
sh.xargexit = exitval; sh.xargexit = exitval;
if(saveargs) if(saveargs)
@ -234,11 +166,7 @@ static pid_t command_xargs(const char *path, char *argv[],char *const envp[], in
{ {
if(saveargs) if(saveargs)
free((void*)saveargs); free((void*)saveargs);
#if SHOPT_PFSH
return(pf_execve(path,argv,envp,spawn));
#else
return(execve(path,argv,envp)); return(execve(path,argv,envp));
#endif
} }
} }
if(!spawn) if(!spawn)
@ -1242,17 +1170,10 @@ pid_t path_spawn(const char *opath,register char **argv, char **envp, Pathcomp_t
} }
else else
#endif #endif
#if SHOPT_PFSH
if(spawn && !sh_isoption(SH_PFSH))
pid = _spawnveg(opath, &argv[0], envp, spawn>>1);
else
pid = pf_execve(opath, &argv[0], envp, spawn);
#else
if(spawn) if(spawn)
pid = _spawnveg(opath, &argv[0], envp, spawn>>1); pid = _spawnveg(opath, &argv[0], envp, spawn>>1);
else else
pid = execve(opath, &argv[0], envp); pid = execve(opath, &argv[0], envp);
#endif /* SHOPT_PFSH */
if(xp) if(xp)
*xp = xval; *xp = xval;
#ifdef SHELLMAGIC #ifdef SHELLMAGIC
@ -1365,7 +1286,7 @@ static noreturn void exscript(register char *path,register char *argv[],char **e
sh_close(sh.infd); sh_close(sh.infd);
sh_setstate(sh_state(SH_FORKED)); sh_setstate(sh_state(SH_FORKED));
sfsync(sfstderr); sfsync(sfstderr);
#if SHOPT_SUID_EXEC && !SHOPT_PFSH #if SHOPT_SUID_EXEC
/* check if file cannot open for read or script is setuid/setgid */ /* check if file cannot open for read or script is setuid/setgid */
{ {
static char name[] = "/tmp/euidXXXXXXXXXX"; static char name[] = "/tmp/euidXXXXXXXXXX";
@ -1401,11 +1322,7 @@ static noreturn void exscript(register char *path,register char *argv[],char **e
} }
savet = *--argv; savet = *--argv;
*argv = path; *argv = path;
#if SHOPT_PFSH
pf_execve(e_suidexec,argv,envp,0);
#else
execve(e_suidexec,argv,envp); execve(e_suidexec,argv,envp);
#endif
fail: fail:
/* /*
* The following code is just for compatibility * The following code is just for compatibility

View file

@ -2,7 +2,7 @@
* * * *
* This software is part of the ast package * * This software is part of the ast package *
* Copyright (c) 1982-2011 AT&T Intellectual Property * * Copyright (c) 1982-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2021 Contributors to ksh 93u+m * * Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the * * and is licensed under the *
* Eclipse Public License, Version 1.0 * * Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property * * by AT&T Intellectual Property *

View file

@ -60,7 +60,6 @@
#endif #endif
#define SH_NTFORK SH_TIMING #define SH_NTFORK SH_TIMING
#define NV_BLTPFSH NV_ARRAY
#if _lib_nice #if _lib_nice
extern int nice(int); extern int nice(int);
@ -1026,19 +1025,6 @@ int sh_exec(register const Shnode_t *t, int flags)
#endif /* SHOPT_NAMESPACE */ #endif /* SHOPT_NAMESPACE */
np = dtsearch(sh.fun_tree,np); np = dtsearch(sh.fun_tree,np);
} }
#if SHOPT_PFSH
if(sh_isoption(SH_PFSH) && nv_isattr(np,NV_BLTINOPT) && !nv_isattr(np,NV_BLTPFSH))
{
if(path_xattr(np->nvname,(char*)0))
{
dtdelete(sh.bltin_tree,np);
np = 0;
}
else
nv_onattr(np,NV_BLTPFSH);
}
#endif /* SHOPT_PFSH */
} }
if(com0) if(com0)
{ {
@ -1084,12 +1070,11 @@ int sh_exec(register const Shnode_t *t, int flags)
flgs |= NV_MOVE; flgs |= NV_MOVE;
if(np==SYSNAMEREF || checkopt(com,'n')) if(np==SYSNAMEREF || checkopt(com,'n'))
flgs |= NV_NOREF; flgs |= NV_NOREF;
#if SHOPT_TYPEDEF
else if(argn>=3 && checkopt(com,'T')) else if(argn>=3 && checkopt(com,'T'))
{ {
if(sh.subshell && !sh.subshare) if(sh.subshell && !sh.subshare)
sh_subfork(); sh_subfork();
# if SHOPT_NAMESPACE #if SHOPT_NAMESPACE
if(sh.namespace) if(sh.namespace)
{ {
if(!sh.strbuf2) if(!sh.strbuf2)
@ -1099,12 +1084,11 @@ int sh_exec(register const Shnode_t *t, int flags)
nv_open(sh.prefix,sh.var_base,NV_VARNAME); nv_open(sh.prefix,sh.var_base,NV_VARNAME);
} }
else else
# endif /* SHOPT_NAMESPACE */ #endif /* SHOPT_NAMESPACE */
sh.prefix = NV_CLASS; sh.prefix = NV_CLASS;
flgs |= NV_TYPE; flgs |= NV_TYPE;
} }
#endif /* SHOPT_TYPEDEF */
if(sh.fn_depth && !sh.prefix) if(sh.fn_depth && !sh.prefix)
flgs |= NV_NOSCOPE; flgs |= NV_NOSCOPE;
} }
@ -2067,7 +2051,7 @@ int sh_exec(register const Shnode_t *t, int flags)
case TLST: case TLST:
{ {
/* a list of commands are executed here */ /* a list of commands is executed here */
do do
{ {
sh_exec(t->lst.lstlef,errorflg|OPTIMIZE); sh_exec(t->lst.lstlef,errorflg|OPTIMIZE);
@ -2215,7 +2199,6 @@ int sh_exec(register const Shnode_t *t, int flags)
sh.st.execbrk = (--sh.st.breakcnt !=0); sh.st.execbrk = (--sh.st.breakcnt !=0);
sh.st.loopcnt--; sh.st.loopcnt--;
sh_argfree(argsav,0); sh_argfree(argsav,0);
nv_close(np);
break; break;
} }
@ -2453,10 +2436,7 @@ int sh_exec(register const Shnode_t *t, int flags)
{ {
Namval_t *np = nv_open("TIMEFORMAT",sh.var_tree,NV_NOADD); Namval_t *np = nv_open("TIMEFORMAT",sh.var_tree,NV_NOADD);
if(np) if(np)
{
format = nv_getval(np); format = nv_getval(np);
nv_close(np);
}
if(!format) if(!format)
format = e_timeformat; format = e_timeformat;
} }

View file

@ -2,7 +2,7 @@
# # # #
# This software is part of the ast package # # This software is part of the ast package #
# Copyright (c) 1982-2012 AT&T Intellectual Property # # Copyright (c) 1982-2012 AT&T Intellectual Property #
# Copyright (c) 2020-2021 Contributors to ksh 93u+m # # Copyright (c) 2020-2022 Contributors to ksh 93u+m #
# and is licensed under the # # and is licensed under the #
# Eclipse Public License, Version 1.0 # # Eclipse Public License, Version 1.0 #
# by AT&T Intellectual Property # # by AT&T Intellectual Property #

View file

@ -678,6 +678,16 @@ got=$(eval 'x=${ for i in test; do case $i in test) true;; esac; done; }' 2>&1)
got=$(eval 'x=`for i in test; do case $i in test) true;; esac; done`' 2>&1) \ got=$(eval 'x=`for i in test; do case $i in test) true;; esac; done`' 2>&1) \
|| err_exit "case in a for loop inside a \`comsub\` caused syntax error (got $(printf %q "$got"))" || err_exit "case in a for loop inside a \`comsub\` caused syntax error (got $(printf %q "$got"))"
# another obscure thing that got fixed as a side effect: literal here-
# document terminator '$( a b )' (no, it's not a command substitution)
exp=$'ok\nend'
saveLINENO=$LINENO
got=$(set +x; eval $'cat <<$( a b )\nok\n$( a b )\necho end' 2>&1)
((LINENO == saveLINENO + 2)) || err_exit "LINENO just got reset (expected $((saveLINENO + 2)), got $LINENO)"
LINENO=saveLINENO+3
[[ $got == "$exp" ]] || err_exit 'pathological here-document terminator $( a b ) fails' \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
# ====== # ======
# Various DEBUG trap fixes: https://github.com/ksh93/ksh/issues/155 # Various DEBUG trap fixes: https://github.com/ksh93/ksh/issues/155
# https://github.com/ksh93/ksh/issues/187 # https://github.com/ksh93/ksh/issues/187

View file

@ -2,7 +2,7 @@
# # # #
# This software is part of the ast package # # This software is part of the ast package #
# Copyright (c) 1982-2012 AT&T Intellectual Property # # Copyright (c) 1982-2012 AT&T Intellectual Property #
# Copyright (c) 2020-2021 Contributors to ksh 93u+m # # Copyright (c) 2020-2022 Contributors to ksh 93u+m #
# and is licensed under the # # and is licensed under the #
# Eclipse Public License, Version 1.0 # # Eclipse Public License, Version 1.0 #
# by AT&T Intellectual Property # # by AT&T Intellectual Property #

View file

@ -2,7 +2,7 @@
# # # #
# This software is part of the ast package # # This software is part of the ast package #
# Copyright (c) 1982-2012 AT&T Intellectual Property # # Copyright (c) 1982-2012 AT&T Intellectual Property #
# Copyright (c) 2020-2021 Contributors to ksh 93u+m # # Copyright (c) 2020-2022 Contributors to ksh 93u+m #
# and is licensed under the # # and is licensed under the #
# Eclipse Public License, Version 1.0 # # Eclipse Public License, Version 1.0 #
# by AT&T Intellectual Property # # by AT&T Intellectual Property #

View file

@ -2,7 +2,7 @@
# # # #
# This software is part of the ast package # # This software is part of the ast package #
# Copyright (c) 1982-2012 AT&T Intellectual Property # # Copyright (c) 1982-2012 AT&T Intellectual Property #
# Copyright (c) 2020-2021 Contributors to ksh 93u+m # # Copyright (c) 2020-2022 Contributors to ksh 93u+m #
# and is licensed under the # # and is licensed under the #
# Eclipse Public License, Version 1.0 # # Eclipse Public License, Version 1.0 #
# by AT&T Intellectual Property # # by AT&T Intellectual Property #

View file

@ -2,7 +2,7 @@
# # # #
# This software is part of the ast package # # This software is part of the ast package #
# Copyright (c) 1982-2011 AT&T Intellectual Property # # Copyright (c) 1982-2011 AT&T Intellectual Property #
# Copyright (c) 2020-2021 Contributors to ksh 93u+m # # Copyright (c) 2020-2022 Contributors to ksh 93u+m #
# and is licensed under the # # and is licensed under the #
# Eclipse Public License, Version 1.0 # # Eclipse Public License, Version 1.0 #
# by AT&T Intellectual Property # # by AT&T Intellectual Property #
@ -278,6 +278,17 @@ exp=''
got=$(unset var; set +x; eval 'echo ${var+'\''{}'\''}' 2>&1) got=$(unset var; set +x; eval 'echo ${var+'\''{}'\''}' 2>&1)
[[ $got == "$exp" ]] || err_exit "Single quotes misparsed in expansion operator string (6)" \ [[ $got == "$exp" ]] || err_exit "Single quotes misparsed in expansion operator string (6)" \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))" "(expected $(printf %q "$exp"), got $(printf %q "$got"))"
# https://github.com/ksh93/ksh/commit/5ed4c71
unset var
exp='text between expansions'
got="${var:+'}text between expansions${var:+'}"
[[ $got == "$exp" ]] || err_exit "Single quotes misparsed in expansion operator string (7)" \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
var=foo
exp=\''text between expansions'\'
got="${var:+'}text between expansions${var:+'}"
[[ $got == "$exp" ]] || err_exit "Single quotes misparsed in expansion operator string (8)" \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
# ====== # ======
exit $((Errors<125?Errors:125)) exit $((Errors<125?Errors:125))

View file

@ -2,7 +2,7 @@
* * * *
* This software is part of the ast package * * This software is part of the ast package *
* Copyright (c) 1985-2011 AT&T Intellectual Property * * Copyright (c) 1985-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2021 Contributors to ksh 93u+m * * Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the * * and is licensed under the *
* Eclipse Public License, Version 1.0 * * Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property * * by AT&T Intellectual Property *
@ -544,7 +544,7 @@ skip:
{ {
/* /*
* For security and usability, only match '..' or '.' as the final element if: * For security and usability, only match '..' or '.' as the final element if:
* - its' specified literally, or * - it's specified literally, or
* - we're in file name completion mode. * - we're in file name completion mode.
* To avoid breaking globstar, make sure that '.' or '..' is skipped if, and only if, it is the * To avoid breaking globstar, make sure that '.' or '..' is skipped if, and only if, it is the
* final element in the pattern (i.e., if 'pat' does not contain a slash) and is not specified * final element in the pattern (i.e., if 'pat' does not contain a slash) and is not specified