From 850460c0f1891b03bde0193ca5af32fd6ed2ba53 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sat, 1 Jan 2011 13:26:18 +0000 Subject: [PATCH] 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 --- bin/sh/eval.c | 3 +-- bin/sh/var.c | 8 ++++++-- bin/sh/var.h | 3 ++- tools/regression/bin/sh/errors/assignment-error2.0 | 8 ++++++++ 4 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 tools/regression/bin/sh/errors/assignment-error2.0 diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 25c3fcf237fe..14dd15f75cd0 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -997,8 +997,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) */ if (argc == 0 && !(flags & EV_BACKCMD)) cmdentry.special = 1; - if (cmdentry.special) - listsetvar(cmdenviron); + listsetvar(cmdenviron, cmdentry.special ? 0 : VNOSET); if (argc > 0) bltinsetlocale(); commandname = argv[0]; diff --git a/bin/sh/var.c b/bin/sh/var.c index 6c0618f3e583..e841647ed779 100644 --- a/bin/sh/var.c +++ b/bin/sh/var.c @@ -333,6 +333,8 @@ setvareq(char *s, int flags) len = strchr(s, '=') - s; error("%.*s: is read only", len, s); } + if (flags & VNOSET) + return; INTOFF; if (vp->func && (flags & VNOFUNC) == 0) @@ -365,6 +367,8 @@ setvareq(char *s, int flags) } } /* not found */ + if (flags & VNOSET) + return; vp = ckmalloc(sizeof (*vp)); vp->flags = flags; vp->text = s; @@ -386,13 +390,13 @@ setvareq(char *s, int flags) */ void -listsetvar(struct strlist *list) +listsetvar(struct strlist *list, int flags) { struct strlist *lp; INTOFF; for (lp = list ; lp ; lp = lp->next) { - setvareq(savestr(lp->text), 0); + setvareq(savestr(lp->text), flags); } INTON; } diff --git a/bin/sh/var.h b/bin/sh/var.h index 1ec707be7df3..775db4186e81 100644 --- a/bin/sh/var.h +++ b/bin/sh/var.h @@ -45,6 +45,7 @@ #define VSTACK 0x10 /* text is allocated on the stack */ #define VUNSET 0x20 /* the variable is not set */ #define VNOFUNC 0x40 /* don't call the callback function */ +#define VNOSET 0x80 /* do not set variable - just readonly test */ struct var { @@ -106,7 +107,7 @@ void initvar(void); void setvar(const char *, const char *, int); void setvareq(char *, int); struct strlist; -void listsetvar(struct strlist *); +void listsetvar(struct strlist *, int); char *lookupvar(const char *); char *bltinlookup(const char *, int); void bltinsetlocale(void); diff --git a/tools/regression/bin/sh/errors/assignment-error2.0 b/tools/regression/bin/sh/errors/assignment-error2.0 new file mode 100644 index 000000000000..ff4e62995262 --- /dev/null +++ b/tools/regression/bin/sh/errors/assignment-error2.0 @@ -0,0 +1,8 @@ +# $FreeBSD$ + +set -e +HOME=/ +readonly HOME +cd /sbin +{ HOME=/bin cd; } 2>/dev/null || : +[ "$(pwd)" != /bin ]