diff --git a/Src/Modules/param_private.c b/Src/Modules/param_private.c index 86416c5c5..24545819d 100644 --- a/Src/Modules/param_private.c +++ b/Src/Modules/param_private.c @@ -171,6 +171,7 @@ bin_private(char *nam, char **args, LinkList assigns, Options ops, int func) { int from_typeset = 1; int ofake = fakelevel; /* paranoia in case of recursive call */ + int hasargs = *args != NULL || (assigns && firstnode(assigns)); makeprivate_error = 0; if (!OPT_ISSET(ops, 'P')) { @@ -190,6 +191,9 @@ bin_private(char *nam, char **args, LinkList assigns, Options ops, int func) } ops->ind['g'] = 2; /* force bin_typeset() to behave as "local" */ + if (OPT_ISSET(ops, 'p') || (!hasargs && OPT_ISSET(ops, '+'))) { + return bin_typeset("private", args, assigns, ops, func); + } queue_signals(); fakelevel = locallevel; diff --git a/Src/builtin.c b/Src/builtin.c index 09eb3728c..3d52d563f 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2612,7 +2612,12 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) int on = 0, off = 0, roff, bit = PM_ARRAY; int i; int returnval = 0, printflags = 0; - int hasargs; + int hasargs = *argv != NULL || (assigns && firstnode(assigns)); + + /* POSIXBUILTINS is set for bash/ksh and both ignore -p with args */ + if ((func == BIN_READONLY || func == BIN_EXPORT) && + isset(POSIXBUILTINS) && hasargs) + ops->ind['p'] = 0; /* hash -f is really the builtin `functions' */ if (OPT_ISSET(ops,'f')) @@ -2692,7 +2697,6 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func) /* -p0 treated as -p for consistency */ } } - hasargs = *argv != NULL || (assigns && firstnode(assigns)); if (!hasargs) { int exclude = 0; if (!OPT_ISSET(ops,'p')) { diff --git a/Src/params.c b/Src/params.c index 122f5da7d..29c1653af 100644 --- a/Src/params.c +++ b/Src/params.c @@ -5867,8 +5867,12 @@ printparamnode(HashNode hn, int printflags) * don't. */ if (printflags & PRINT_POSIX_EXPORT) { + if (!(p->node.flags & PM_EXPORTED)) + return; printf("export "); } else if (printflags & PRINT_POSIX_READONLY) { + if (!(p->node.flags & PM_READONLY)) + return; printf("readonly "); } else if (locallevel && p->level >= locallevel) { printf("typeset "); /* printf("local "); */ diff --git a/Test/B02typeset.ztst b/Test/B02typeset.ztst index e7bf93794..8b3988151 100644 --- a/Test/B02typeset.ztst +++ b/Test/B02typeset.ztst @@ -620,7 +620,7 @@ print ${+pbro} >&2 (typeset -g pbro=3) (pbro=4) - readonly -p pbro >&2 # shows up as "readonly" although unset + readonly -p >&2 # shows up as "readonly" although unset typeset -gr pbro # idempotent (no error)... print ${+pbro} >&2 # ...so still readonly... typeset -g +r pbro # ...can't turn it off @@ -1050,23 +1050,21 @@ $ZTST_testdir/../Src/zsh --emulate sh -f -c ' PATH=/bin; export PATH; readonly PATH - export -p PATH + export -p PATH # Should be a no-op, -p ignored typeset -p PATH readonly -p' 0: readonly/export output for exported+readonly+special when started as sh ->export PATH=/bin >export -r PATH=/bin >readonly PATH=/bin function { emulate -L sh MANPATH=/bin; export MANPATH; readonly MANPATH - export -p MANPATH + export -p MANPATH # Should be a no-op, -p ignored typeset -p MANPATH readonly -p } 0: readonly/export output for exported+readonly+tied+special after switching to sh emulation ->export MANPATH=/bin >export -rT MANPATH manpath=( /bin ) >readonly MANPATH=/bin