sh: Check readonly status for assignments on regular builtins.
An error message is written, the builtin is not executed, nonzero exit status is returned but the shell does not abort. This was already checked for special builtins and external commands, with the same consequences except that the shell aborts for special builtins. Obtained from: NetBSD
This commit is contained in:
parent
5610751bf1
commit
850460c0f1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=216870
@ -997,8 +997,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
|
|||||||
*/
|
*/
|
||||||
if (argc == 0 && !(flags & EV_BACKCMD))
|
if (argc == 0 && !(flags & EV_BACKCMD))
|
||||||
cmdentry.special = 1;
|
cmdentry.special = 1;
|
||||||
if (cmdentry.special)
|
listsetvar(cmdenviron, cmdentry.special ? 0 : VNOSET);
|
||||||
listsetvar(cmdenviron);
|
|
||||||
if (argc > 0)
|
if (argc > 0)
|
||||||
bltinsetlocale();
|
bltinsetlocale();
|
||||||
commandname = argv[0];
|
commandname = argv[0];
|
||||||
|
@ -333,6 +333,8 @@ setvareq(char *s, int flags)
|
|||||||
len = strchr(s, '=') - s;
|
len = strchr(s, '=') - s;
|
||||||
error("%.*s: is read only", len, s);
|
error("%.*s: is read only", len, s);
|
||||||
}
|
}
|
||||||
|
if (flags & VNOSET)
|
||||||
|
return;
|
||||||
INTOFF;
|
INTOFF;
|
||||||
|
|
||||||
if (vp->func && (flags & VNOFUNC) == 0)
|
if (vp->func && (flags & VNOFUNC) == 0)
|
||||||
@ -365,6 +367,8 @@ setvareq(char *s, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* not found */
|
/* not found */
|
||||||
|
if (flags & VNOSET)
|
||||||
|
return;
|
||||||
vp = ckmalloc(sizeof (*vp));
|
vp = ckmalloc(sizeof (*vp));
|
||||||
vp->flags = flags;
|
vp->flags = flags;
|
||||||
vp->text = s;
|
vp->text = s;
|
||||||
@ -386,13 +390,13 @@ setvareq(char *s, int flags)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
listsetvar(struct strlist *list)
|
listsetvar(struct strlist *list, int flags)
|
||||||
{
|
{
|
||||||
struct strlist *lp;
|
struct strlist *lp;
|
||||||
|
|
||||||
INTOFF;
|
INTOFF;
|
||||||
for (lp = list ; lp ; lp = lp->next) {
|
for (lp = list ; lp ; lp = lp->next) {
|
||||||
setvareq(savestr(lp->text), 0);
|
setvareq(savestr(lp->text), flags);
|
||||||
}
|
}
|
||||||
INTON;
|
INTON;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#define VSTACK 0x10 /* text is allocated on the stack */
|
#define VSTACK 0x10 /* text is allocated on the stack */
|
||||||
#define VUNSET 0x20 /* the variable is not set */
|
#define VUNSET 0x20 /* the variable is not set */
|
||||||
#define VNOFUNC 0x40 /* don't call the callback function */
|
#define VNOFUNC 0x40 /* don't call the callback function */
|
||||||
|
#define VNOSET 0x80 /* do not set variable - just readonly test */
|
||||||
|
|
||||||
|
|
||||||
struct var {
|
struct var {
|
||||||
@ -106,7 +107,7 @@ void initvar(void);
|
|||||||
void setvar(const char *, const char *, int);
|
void setvar(const char *, const char *, int);
|
||||||
void setvareq(char *, int);
|
void setvareq(char *, int);
|
||||||
struct strlist;
|
struct strlist;
|
||||||
void listsetvar(struct strlist *);
|
void listsetvar(struct strlist *, int);
|
||||||
char *lookupvar(const char *);
|
char *lookupvar(const char *);
|
||||||
char *bltinlookup(const char *, int);
|
char *bltinlookup(const char *, int);
|
||||||
void bltinsetlocale(void);
|
void bltinsetlocale(void);
|
||||||
|
8
tools/regression/bin/sh/errors/assignment-error2.0
Normal file
8
tools/regression/bin/sh/errors/assignment-error2.0
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
set -e
|
||||||
|
HOME=/
|
||||||
|
readonly HOME
|
||||||
|
cd /sbin
|
||||||
|
{ HOME=/bin cd; } 2>/dev/null || :
|
||||||
|
[ "$(pwd)" != /bin ]
|
Loading…
Reference in New Issue
Block a user