2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1997-2005
5 * Herbert Xu <herbert@gondor.apana.org.au>. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49 #include "nodes.h" /* for other headers */
61 #include "myhistedit.h"
69 struct localvar_list
{
70 struct localvar_list
*next
;
74 MKINIT
struct localvar_list
*localvar_stack
;
76 const char defpathvar
[] =
77 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
78 char defifsvar
[] = "IFS= \t\n";
79 MKINIT
char defoptindvar
[] = "OPTIND=1";
82 char linenovar
[sizeof("LINENO=")+sizeof(int)*CHAR_BIT
/3+1] = "LINENO=";
84 /* Some macros in var.h depend on the order, add new variables to the end. */
85 struct var varinit
[] = {
87 { 0, VSTRFIXED
|VTEXTFIXED
|VUNSET
, "ATTY\0", 0 },
89 { 0, VSTRFIXED
|VTEXTFIXED
, defifsvar
, 0 },
90 { 0, VSTRFIXED
|VTEXTFIXED
|VUNSET
, "MAIL\0", changemail
},
91 { 0, VSTRFIXED
|VTEXTFIXED
|VUNSET
, "MAILPATH\0", changemail
},
92 { 0, VSTRFIXED
|VTEXTFIXED
, defpathvar
, changepath
},
93 { 0, VSTRFIXED
|VTEXTFIXED
, "PS1=$ ", 0 },
94 { 0, VSTRFIXED
|VTEXTFIXED
, "PS2=> ", 0 },
95 { 0, VSTRFIXED
|VTEXTFIXED
, "PS4=+ ", 0 },
96 { 0, VSTRFIXED
|VTEXTFIXED
, defoptindvar
, getoptsreset
},
98 { 0, VSTRFIXED
|VTEXTFIXED
, linenovar
, 0 },
101 { 0, VSTRFIXED
|VTEXTFIXED
|VUNSET
, "TERM\0", 0 },
102 { 0, VSTRFIXED
|VTEXTFIXED
|VUNSET
, "HISTSIZE\0", sethistsize
},
106 STATIC
struct var
*vartab
[VTABSIZE
];
108 STATIC
struct var
**hashvar(const char *);
109 STATIC
int vpcmp(const void *, const void *);
110 STATIC
struct var
**findvar(struct var
**, const char *);
113 * Initialize the varable symbol tables and import the environment
118 INCLUDE
<sys
/types
.h
>
123 MKINIT
char **environ
;
126 static char ppid
[32] = "PPID=";
128 struct stat64 st1
, st2
;
131 for (envp
= environ
; *envp
; envp
++) {
132 p
= endofname(*envp
);
133 if (p
!= *envp
&& *p
== '=') {
134 setvareq(*envp
, VEXPORT
|VTEXTFIXED
);
138 setvareq(defifsvar
, VTEXTFIXED
);
139 setvareq(defoptindvar
, VTEXTFIXED
);
141 fmtstr(ppid
+ 5, sizeof(ppid
) - 5, "%ld", (long) getppid());
142 setvareq(ppid
, VTEXTFIXED
);
144 p
= lookupvar("PWD");
146 if (*p
!= '/' || stat64(p
, &st1
) || stat64(".", &st2
) ||
147 st1
.st_dev
!= st2
.st_dev
|| st1
.st_ino
!= st2
.st_ino
)
159 * This routine initializes the builtin variables. It is called when the
160 * shell is initialized.
171 end
= vp
+ sizeof(varinit
) / sizeof(varinit
[0]);
173 vpp
= hashvar(vp
->text
);
176 } while (++vp
< end
);
181 vps1
.text
= "PS1=# ";
185 * Set the value of a variable. The flags argument is ored with the
186 * flags of the variable. If val is NULL, the variable is unset.
189 struct var
*setvar(const char *name
, const char *val
, int flags
)
198 p
= strchrnul(q
, '=');
200 if (!namelen
|| p
!= q
)
201 sh_error("%.*s: bad variable name", namelen
, name
);
206 vallen
= strlen(val
);
209 p
= mempcpy(nameeq
= ckmalloc(namelen
+ vallen
+ 2), name
, namelen
);
212 p
= mempcpy(p
, val
, vallen
);
215 vp
= setvareq(nameeq
, flags
| VNOSAVE
);
222 * Set the given integer as the value of a variable. The flags argument is
223 * ored with the flags of the variable.
226 intmax_t setvarint(const char *name
, intmax_t val
, int flags
)
228 int len
= max_int_length(sizeof(val
));
231 fmtstr(buf
, len
, "%" PRIdMAX
, val
);
232 setvar(name
, buf
, flags
);
239 * Same as setvar except that the variable and value are passed in
240 * the first argument as name=value. Since the first argument will
241 * be actually stored in the table, it should not be a string that
243 * Called with interrupts off.
246 struct var
*setvareq(char *s
, int flags
)
248 struct var
*vp
, **vpp
;
251 flags
|= (VEXPORT
& (((unsigned) (1 - aflag
)) - 1));
252 vpp
= findvar(vpp
, s
);
255 if (vp
->flags
& VREADONLY
) {
261 sh_error("%.*s: is read only", strchrnul(n
, '=') - n
,
268 if (vp
->func
&& (flags
& VNOFUNC
) == 0)
269 (*vp
->func
)(strchrnul(s
, '=') + 1);
271 if ((vp
->flags
& (VTEXTFIXED
|VSTACK
)) == 0)
274 if (((flags
& (VEXPORT
|VREADONLY
|VSTRFIXED
|VUNSET
)) |
275 (vp
->flags
& VSTRFIXED
)) == VUNSET
) {
279 if ((flags
& (VTEXTFIXED
|VSTACK
|VNOSAVE
)) == VNOSAVE
)
284 flags
|= vp
->flags
& ~(VTEXTFIXED
|VSTACK
|VNOSAVE
|VUNSET
);
288 if ((flags
& (VEXPORT
|VREADONLY
|VSTRFIXED
|VUNSET
)) == VUNSET
)
291 vp
= ckmalloc(sizeof (*vp
));
296 if (!(flags
& (VTEXTFIXED
|VSTACK
|VNOSAVE
)))
306 * Find the value of a variable. Returns NULL if not set.
310 lookupvar(const char *name
)
314 if ((v
= *findvar(hashvar(name
), name
)) && !(v
->flags
& VUNSET
)) {
316 if (v
== &vlineno
&& v
->text
== linenovar
) {
317 fmtstr(linenovar
+7, sizeof(linenovar
)-7, "%d", lineno
);
320 return strchrnul(v
->text
, '=') + 1;
325 intmax_t lookupvarint(const char *name
)
327 return atomax(lookupvar(name
) ?: nullstr
, 0);
333 * Generate a list of variables satisfying the given conditions.
337 listvars(int on
, int off
, char ***end
)
348 for (vp
= *vpp
; vp
; vp
= vp
->next
)
349 if ((vp
->flags
& mask
) == on
) {
350 if (ep
== stackstrend())
352 *ep
++ = (char *) vp
->text
;
354 } while (++vpp
< vartab
+ VTABSIZE
);
355 if (ep
== stackstrend())
360 return grabstackstr(ep
);
366 * POSIX requires that 'set' (but not export or readonly) output the
367 * variables in lexicographic order - by the locale's collating order (sigh).
368 * Maybe we could keep them in an ordered balanced binary tree
369 * instead of hashed lists.
370 * For now just roll 'em through qsort for printing...
374 showvars(const char *prefix
, int on
, int off
)
379 ep
= listvars(on
, off
, &epend
);
380 qsort(ep
, epend
- ep
, sizeof(char *), vpcmp
);
382 sep
= *prefix
? spcstr
: prefix
;
384 for (; ep
< epend
; ep
++) {
388 p
= strchrnul(*ep
, '=');
391 q
= single_quote(++p
);
393 out1fmt("%s%s%.*s%s\n", prefix
, sep
, (int)(p
- *ep
), *ep
, q
);
402 * The export and readonly commands.
406 exportcmd(int argc
, char **argv
)
412 int flag
= argv
[0][0] == 'r'? VREADONLY
: VEXPORT
;
415 notp
= nextopt("p") - 'p';
416 if (notp
&& ((name
= *(aptr
= argptr
)))) {
418 if ((p
= strchr(name
, '=')) != NULL
) {
421 if ((vp
= *findvar(hashvar(name
), name
))) {
426 setvar(name
, p
, flag
);
427 } while ((name
= *++aptr
) != NULL
);
429 showvars(argv
[0], flag
, 0);
436 * The "local" command.
440 localcmd(int argc
, char **argv
)
445 sh_error("not in a function");
448 while ((name
= *argv
++) != NULL
) {
456 * Make a variable a local variable. When a variable is made local, it's
457 * value and flags are saved in a localvar structure. The saved values
458 * will be restored when the shell function returns. We handle the name
459 * "-" as a special case.
462 void mklocal(char *name
, int flags
)
464 struct localvar
*lvp
;
469 lvp
= ckmalloc(sizeof (struct localvar
));
470 if (name
[0] == '-' && name
[1] == '\0') {
472 p
= ckmalloc(sizeof(optlist
));
473 lvp
->text
= memcpy(p
, optlist
, sizeof(optlist
));
479 vp
= *findvar(vpp
, name
);
480 eq
= strchr(name
, '=');
483 vp
= setvareq(name
, VSTRFIXED
| flags
);
485 vp
= setvar(name
, NULL
, VSTRFIXED
| flags
);
488 lvp
->text
= vp
->text
;
489 lvp
->flags
= vp
->flags
;
490 vp
->flags
|= VSTRFIXED
|VTEXTFIXED
;
492 setvareq(name
, flags
);
496 lvp
->next
= localvar_stack
->lv
;
497 localvar_stack
->lv
= lvp
;
503 * Called after a function returns.
504 * Interrupts must be off.
510 struct localvar_list
*ll
;
511 struct localvar
*lvp
, *next
;
516 localvar_stack
= ll
->next
;
521 while ((lvp
= next
) != NULL
) {
524 TRACE(("poplocalvar %s\n", vp
? vp
->text
: "-"));
525 if (vp
== NULL
) { /* $- saved */
526 memcpy(optlist
, lvp
->text
, sizeof(optlist
));
529 } else if (lvp
->flags
== VUNSET
) {
530 vp
->flags
&= ~(VSTRFIXED
|VREADONLY
);
534 (*vp
->func
)(strchrnul(lvp
->text
, '=') + 1);
535 if ((vp
->flags
& (VTEXTFIXED
|VSTACK
)) == 0)
537 vp
->flags
= lvp
->flags
;
538 vp
->text
= lvp
->text
;
547 * Create a new localvar environment.
549 struct localvar_list
*pushlocalvars(int push
)
551 struct localvar_list
*ll
;
552 struct localvar_list
*top
;
554 top
= localvar_stack
;
559 ll
= ckmalloc(sizeof(*ll
));
570 void unwindlocalvars(struct localvar_list
*stop
)
572 while (localvar_stack
!= stop
)
578 * The unset builtin command. We unset the function before we unset the
579 * variable to allow a function to be unset when there is a readonly variable
580 * with the same name.
584 unsetcmd(int argc
, char **argv
)
590 while ((i
= nextopt("vf")) != '\0') {
594 for (ap
= argptr
; *ap
; ap
++) {
607 * Unset the specified variable.
610 void unsetvar(const char *s
)
618 * Find the appropriate entry in the hash table from the name.
622 hashvar(const char *p
)
624 unsigned int hashval
;
626 hashval
= ((unsigned char) *p
) << 4;
627 while (*p
&& *p
!= '=')
628 hashval
+= (unsigned char) *p
++;
629 return &vartab
[hashval
% VTABSIZE
];
635 * Compares two strings up to the first = or '\0'. The first
636 * string must be terminated by '='; the second may be terminated by
637 * either '=' or '\0'.
641 varcmp(const char *p
, const char *q
)
645 while ((c
= *p
) == (d
= *q
)) {
660 vpcmp(const void *a
, const void *b
)
662 return varcmp(*(const char **)a
, *(const char **)b
);
666 findvar(struct var
**vpp
, const char *name
)
668 for (; *vpp
; vpp
= &(*vpp
)->next
) {
669 if (varequal((*vpp
)->text
, name
)) {