summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--Doc/Zsh/builtins.yo4
-rw-r--r--Doc/Zsh/params.yo8
-rw-r--r--Src/builtin.c9
-rw-r--r--Src/params.c4
5 files changed, 24 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 882719631..da46434a2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2001-06-14  Peter Stephenson  <pws@csr.com>
+
+	* 14915: Doc/Zsh/builtins.yo, Doc/Zsh/Params.yo, Src/builtin.c,
+	Src/params.c: special parameters can't have readonly turned off;
+	$* and $@ are readonly.
+
 2001-06-13  Sven Wischnowsky  <wischnow@zsh.org>
 
 	* 14903: Src/Zle/complist.c, Src/Zle/zle_tricky.c: fixes for
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index fbea91ee2..a65af889e 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -1192,7 +1192,9 @@ Convert the result to lower case whenever the parameter is expanded.
 The value is em(not) converted when assigned.
 )
 item(tt(-r))(
-The given var(name)s are marked readonly.
+The given var(name)s are marked readonly.  Note that if var(name) is a
+special parameter, the readonly attribute can be turned on, but cannot then
+be turned off.
 )
 item(tt(-t))(
 Tags the named parameters.  Tags have no special meaning to the shell.
diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo
index 194c475e7..5a9c72ace 100644
--- a/Doc/Zsh/params.yo
+++ b/Doc/Zsh/params.yo
@@ -31,9 +31,11 @@ for complete details.
 
 In the parameter lists that follow, the mark `<S>' indicates that the
 parameter is special.
-Special parameters cannot have their type changed, and they stay special even
-if unset.  `<Z>' indicates that the parameter does not exist when the shell
-initializes in tt(sh) or tt(ksh) emulation mode.
+Special parameters cannot have their type changed or their
+readonly attribute turned off, and if a special parameter is unset, then
+later recreated, the special properties will be retained.  `<Z>' indicates
+that the parameter does not exist when the shell initializes in tt(sh) or
+tt(ksh) emulation mode.
 startmenu()
 menu(Array Parameters)
 menu(Positional Parameters)
diff --git a/Src/builtin.c b/Src/builtin.c
index ad340afc8..110a264f2 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -1628,7 +1628,14 @@ typeset_single(char *cname, char *pname, Param pm, int func,
 	if ((tc = chflags && chflags != (PM_EFLOAT|PM_FFLOAT)))
 	    usepm = 0;
     }
-    if (tc){
+
+    /*
+     * Extra checks if converting the type of a parameter, or if
+     * trying to remove readonlyness.  It's dangerous doing either
+     * with a special or a parameter which isn't loaded yet (which
+     * may be special when it is loaded; we can't tell yet).
+     */
+    if (tc || ((usepm || newspecial) && (off & pm->flags & PM_READONLY))) {
 	if (pm->flags & PM_SPECIAL) {
 	    zerrnam(cname, "%s: can't change type of a special parameter",
 		    pname, 0);
diff --git a/Src/params.c b/Src/params.c
index f4575b56e..7eec34bf4 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -216,8 +216,8 @@ IPDEF8("MODULE_PATH", &module_path, "module_path", PM_DONTIMPORT|PM_RESTRICTED),
 
 #define IPDEF9F(A,B,C,D) {NULL,A,D|PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT,BR((void *)B),SFN(arrvarsetfn),GFN(arrvargetfn),stdunsetfn,0,NULL,C,NULL,0}
 #define IPDEF9(A,B,C) IPDEF9F(A,B,C,0)
-IPDEF9("*", &pparams, NULL),
-IPDEF9("@", &pparams, NULL),
+IPDEF9F("*", &pparams, NULL, PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT|PM_READONLY),
+IPDEF9F("@", &pparams, NULL, PM_ARRAY|PM_SPECIAL|PM_DONTIMPORT|PM_READONLY),
 {NULL, NULL},
 #define IPDEF10(A,B,C) {NULL,A,PM_ARRAY|PM_SPECIAL,BR(NULL),SFN(C),GFN(B),stdunsetfn,10,NULL,NULL,NULL,0}