* SUCH DAMAGE.
*
* @(#)eval.c 8.9 (Berkeley) 6/8/95
- * $FreeBSD: src/bin/sh/eval.c,v 1.108 2011/06/09 23:12:23 jilles Exp $
+ * $FreeBSD: src/bin/sh/eval.c,v 1.109 2011/06/12 23:06:04 jilles Exp $
*/
#include <sys/time.h>
static int
is_valid_fast_cmdsubst(union node *n)
{
- union node *argp;
- if (n->type != NCMD)
- return 0;
- for (argp = n->ncmd.args ; argp ; argp = argp->narg.next)
- if (expandhassideeffects(argp->narg.text))
- return 0;
- return 1;
+ return (n->type == NCMD);
}
/*
struct stackmark smark; /* unnecessary */
struct jmploc jmploc;
struct jmploc *savehandler;
+ struct localvar *savelocalvars;
setstackmark(&smark);
result->fd = -1;
}
if (is_valid_fast_cmdsubst(n)) {
exitstatus = oexitstatus;
+ savelocalvars = localvars;
+ localvars = NULL;
+ forcelocal++;
savehandler = handler;
if (setjmp(jmploc.loc)) {
if (exception == EXERROR || exception == EXEXEC)
exitstatus = 2;
else if (exception != 0) {
handler = savehandler;
+ forcelocal--;
+ poplocalvars();
+ localvars = savelocalvars;
longjmp(handler->loc, 1);
}
} else {
evalcommand(n, EV_BACKCMD, result);
}
handler = savehandler;
+ forcelocal--;
+ poplocalvars();
+ localvars = savelocalvars;
} else {
exitstatus = 0;
if (pipe(pip) < 0)
* SUCH DAMAGE.
*
* @(#)expand.c 8.5 (Berkeley) 5/15/95
- * $FreeBSD: src/bin/sh/expand.c,v 1.87 2011/06/09 23:12:23 jilles Exp $
+ * $FreeBSD: src/bin/sh/expand.c,v 1.89 2011/06/12 23:06:04 jilles Exp $
*/
#include <sys/types.h>
}
/*
- * Check statically if expanding a string may have side effects.
- */
-int
-expandhassideeffects(const char *p)
-{
- int c;
- int arinest;
-
- arinest = 0;
- while ((c = *p++) != '\0') {
- switch (c) {
- case CTLESC:
- p++;
- break;
- case CTLVAR:
- c = *p++;
- /* Expanding $! sets the job to remembered. */
- if (*p == '!')
- return 1;
- if ((c & VSTYPE) == VSASSIGN)
- return 1;
- /*
- * If we are in arithmetic, the parameter may contain
- * '=' which may cause side effects. Exceptions are
- * the length of a parameter and $$, $# and $? which
- * are always numeric.
- */
- if ((c & VSTYPE) == VSLENGTH) {
- while (*p != '=')
- p++;
- p++;
- break;
- }
- if ((*p == '$' || *p == '#' || *p == '?') &&
- p[1] == '=') {
- p += 2;
- break;
- }
- if (arinest > 0)
- return 1;
- break;
- case CTLBACKQ:
- case CTLBACKQ | CTLQUOTE:
- if (arinest > 0)
- return 1;
- break;
- case CTLARI:
- arinest++;
- break;
- case CTLENDARI:
- arinest--;
- break;
- case '=':
- if (*p == '=') {
- /* Allow '==' operator. */
- p++;
- continue;
- }
- if (arinest > 0)
- return 1;
- break;
- case '!': case '<': case '>':
- /* Allow '!=', '<=', '>=' operators. */
- if (*p == '=')
- p++;
- break;
- }
- }
- return 0;
-}
-
-/*
* Do most of the work for wordexp(3).
*/
* SUCH DAMAGE.
*
* @(#)expand.h 8.2 (Berkeley) 5/4/95
- * $FreeBSD: src/bin/sh/expand.h,v 1.15 2010/12/28 21:27:08 jilles Exp $
+ * $FreeBSD: src/bin/sh/expand.h,v 1.16 2011/06/12 23:06:04 jilles Exp $
*/
struct strlist {
int patmatch(const char *, const char *, int);
void rmescapes(char *);
int casematch(union node *, const char *);
-int expandhassideeffects(const char *);
int wordexpcmd(int, char **);
* SUCH DAMAGE.
*
* @(#)jobs.c 8.5 (Berkeley) 5/4/95
- * $FreeBSD: src/bin/sh/jobs.c,v 1.93 2011/06/04 15:05:52 jilles Exp $
+ * $FreeBSD: src/bin/sh/jobs.c,v 1.94 2011/06/12 23:06:04 jilles Exp $
*/
#include <sys/ioctl.h>
#include "memalloc.h"
#include "error.h"
#include "mystring.h"
+#include "var.h"
static struct job *jobtab; /* array of jobs */
handler = &main_handler;
closescript();
INTON;
+ forcelocal = 0;
clear_traps();
#if JOBS
jobctl = 0; /* do job control only in root shell */
pid_t
backgndpidval(void)
{
- if (bgjob != NULL)
+ if (bgjob != NULL && !forcelocal)
bgjob->remembered = 1;
return backgndpid;
}
.\" SUCH DAMAGE.
.\"
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
-.\" $FreeBSD: src/bin/sh/sh.1,v 1.167 2011/06/10 22:42:00 jilles Exp $
+.\" $FreeBSD: src/bin/sh/sh.1,v 1.168 2011/06/12 23:06:04 jilles Exp $
.\"
.Dd August 21, 2011
.Dt SH 1
and
.Ic trap
return information about the main shell environment
-if they are the only command in a command substitution
-and the substitutions in the command cannot cause side effects
-(such as from assigning values to variables or referencing
-.Li $! ).
+if they are the only command in a command substitution.
.Ss Arithmetic Expansion
Arithmetic expansion provides a mechanism for evaluating an arithmetic
expression and substituting its value.
* SUCH DAMAGE.
*
* @(#)var.c 8.3 (Berkeley) 5/4/95
- * $FreeBSD: src/bin/sh/var.c,v 1.60 2011/05/15 22:09:27 jilles Exp $
+ * $FreeBSD: src/bin/sh/var.c,v 1.61 2011/06/12 23:06:04 jilles Exp $
*/
#include <unistd.h>
struct var vvers;
static struct var voptind;
+int forcelocal;
+
static const struct varinit varinit[] = {
#ifndef NO_HISTORY
{ &vhistsize, VUNSET, "HISTSIZE=",
if (aflag)
flags |= VEXPORT;
+ if (forcelocal && !(flags & (VNOSET | VNOLOCAL)))
+ mklocal(s);
vp = find_var(s, &vpp, &nlen);
if (vp != NULL) {
if (vp->flags & VREADONLY)
vp = find_var(name, &vpp, NULL);
if (vp == NULL) {
if (strchr(name, '='))
- setvareq(savestr(name), VSTRFIXED);
+ setvareq(savestr(name), VSTRFIXED | VNOLOCAL);
else
- setvar(name, NULL, VSTRFIXED);
+ setvar(name, NULL, VSTRFIXED | VNOLOCAL);
vp = *vpp; /* the new variable */
lvp->text = NULL;
lvp->flags = VUNSET;
lvp->flags = vp->flags;
vp->flags |= VSTRFIXED|VTEXTFIXED;
if (name[vp->name_len] == '=')
- setvareq(savestr(name), 0);
+ setvareq(savestr(name), VNOLOCAL);
}
}
lvp->vp = vp;
* SUCH DAMAGE.
*
* @(#)var.h 8.2 (Berkeley) 5/4/95
- * $FreeBSD: src/bin/sh/var.h,v 1.22 2011/05/08 17:40:10 jilles Exp $
+ * $FreeBSD: src/bin/sh/var.h,v 1.23 2011/06/12 23:06:04 jilles Exp $
*/
/*
#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 */
+#define VNOLOCAL 0x100 /* ignore forcelocal */
struct var {
struct localvar *localvars;
+extern int forcelocal;
extern struct var vifs;
extern struct var vmail;