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
, changeifs
},
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
|VNOFUNC
, 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(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(dotdir
, &st2
) ||
147 st1
.st_dev
!= st2
.st_dev
|| st1
.st_ino
!= st2
.st_ino
)
157 static char *varnull(const char *s
)
159 return (strchr(s
, '=') ?: nullstr
- 1) + 1;
163 * This routine initializes the builtin variables. It is called when the
164 * shell is initialized.
175 end
= vp
+ sizeof(varinit
) / sizeof(varinit
[0]);
177 vpp
= hashvar(vp
->text
);
180 } while (++vp
< end
);
185 vps1
.text
= "PS1=# ";
189 * Set the value of a variable. The flags argument is ored with the
190 * flags of the variable. If val is NULL, the variable is unset.
193 struct var
*setvar(const char *name
, const char *val
, int flags
)
202 p
= strchrnul(q
, '=');
204 if (!namelen
|| p
!= q
)
205 sh_error("%.*s: bad variable name", namelen
, name
);
210 vallen
= strlen(val
);
213 p
= mempcpy(nameeq
= ckmalloc(namelen
+ vallen
+ 2), name
, namelen
);
216 p
= mempcpy(p
, val
, vallen
);
219 vp
= setvareq(nameeq
, flags
| VNOSAVE
);
226 * Set the given integer as the value of a variable. The flags argument is
227 * ored with the flags of the variable.
230 intmax_t setvarint(const char *name
, intmax_t val
, int flags
)
232 int len
= max_int_length(sizeof(val
));
235 fmtstr(buf
, len
, "%" PRIdMAX
, val
);
236 setvar(name
, buf
, flags
);
243 * Same as setvar except that the variable and value are passed in
244 * the first argument as name=value. Since the first argument will
245 * be actually stored in the table, it should not be a string that
247 * Called with interrupts off.
250 struct var
*setvareq(char *s
, int flags
)
252 struct var
*vp
, **vpp
;
254 flags
|= (VEXPORT
& (((unsigned) (1 - aflag
)) - 1));
260 if (vp
->flags
& VREADONLY
) {
266 sh_error("%.*s: is read only", strchrnul(n
, '=') - n
,
270 if ((vp
->flags
& (VTEXTFIXED
|VSTACK
)) == 0)
273 if ((flags
& (VEXPORT
|VREADONLY
|VSTRFIXED
|VUNSET
)) != VUNSET
)
274 bits
= ~(VTEXTFIXED
|VSTACK
|VNOSAVE
|VUNSET
);
275 else if ((vp
->flags
& VSTRFIXED
))
281 if ((flags
& (VTEXTFIXED
|VSTACK
|VNOSAVE
)) == VNOSAVE
)
286 flags
|= vp
->flags
& bits
;
288 if ((flags
& (VEXPORT
|VREADONLY
|VSTRFIXED
|VUNSET
)) == VUNSET
)
291 vp
= ckmalloc(sizeof (*vp
));
296 if (!(flags
& (VTEXTFIXED
|VSTACK
|VNOSAVE
)))
301 if (vp
->func
&& (flags
& VNOFUNC
) == 0)
302 (*vp
->func
)(varnull(s
));
309 * Find the value of a variable. Returns NULL if not set.
313 lookupvar(const char *name
)
317 if ((v
= *findvar(name
)) && !(v
->flags
& VUNSET
)) {
319 if (v
== &vlineno
&& v
->text
== linenovar
) {
320 fmtstr(linenovar
+7, sizeof(linenovar
)-7, "%d", lineno
);
323 return strchrnul(v
->text
, '=') + 1;
328 intmax_t lookupvarint(const char *name
)
330 return atomax(lookupvar(name
) ?: nullstr
, 0);
336 * Generate a list of variables satisfying the given conditions.
340 listvars(int on
, int off
, char ***end
)
351 for (vp
= *vpp
; vp
; vp
= vp
->next
)
352 if ((vp
->flags
& mask
) == on
) {
353 if (ep
== stackstrend())
355 *ep
++ = (char *) vp
->text
;
357 } while (++vpp
< vartab
+ VTABSIZE
);
358 if (ep
== stackstrend())
363 return grabstackstr(ep
);
369 * POSIX requires that 'set' (but not export or readonly) output the
370 * variables in lexicographic order - by the locale's collating order (sigh).
371 * Maybe we could keep them in an ordered balanced binary tree
372 * instead of hashed lists.
373 * For now just roll 'em through qsort for printing...
377 showvars(const char *prefix
, int on
, int off
)
382 ep
= listvars(on
, off
, &epend
);
383 qsort(ep
, epend
- ep
, sizeof(char *), vpcmp
);
385 sep
= *prefix
? spcstr
: prefix
;
387 for (; ep
< epend
; ep
++) {
391 p
= strchrnul(*ep
, '=');
394 q
= single_quote(++p
);
396 out1fmt("%s%s%.*s%s\n", prefix
, sep
, (int)(p
- *ep
), *ep
, q
);
405 * The export and readonly commands.
409 exportcmd(int argc
, char **argv
)
415 int flag
= argv
[0][0] == 'r'? VREADONLY
: VEXPORT
;
418 notp
= nextopt("p") - 'p';
419 if (notp
&& ((name
= *(aptr
= argptr
)))) {
421 if ((p
= strchr(name
, '=')) != NULL
) {
424 if ((vp
= *findvar(name
))) {
429 setvar(name
, p
, flag
);
430 } while ((name
= *++aptr
) != NULL
);
432 showvars(argv
[0], flag
, 0);
439 * The "local" command.
443 localcmd(int argc
, char **argv
)
448 sh_error("not in a function");
451 while ((name
= *argv
++) != NULL
) {
459 * Make a variable a local variable. When a variable is made local, it's
460 * value and flags are saved in a localvar structure. The saved values
461 * will be restored when the shell function returns. We handle the name
462 * "-" as a special case.
465 void mklocal(char *name
, int flags
)
467 struct localvar
*lvp
;
471 lvp
= ckmalloc(sizeof (struct localvar
));
472 if (name
[0] == '-' && name
[1] == '\0') {
474 p
= ckmalloc(sizeof(optlist
));
475 lvp
->text
= memcpy(p
, optlist
, sizeof(optlist
));
481 eq
= strchr(name
, '=');
484 vp
= setvareq(name
, VSTRFIXED
| flags
);
486 vp
= setvar(name
, NULL
, VSTRFIXED
| flags
);
489 lvp
->text
= vp
->text
;
490 lvp
->flags
= vp
->flags
;
491 vp
->flags
|= VSTRFIXED
|VTEXTFIXED
;
493 setvareq(name
, flags
);
497 lvp
->next
= localvar_stack
->lv
;
498 localvar_stack
->lv
= lvp
;
504 * Called after a function returns.
505 * Interrupts must be off.
511 struct localvar_list
*ll
;
512 struct localvar
*lvp
, *next
;
517 localvar_stack
= ll
->next
;
522 while ((lvp
= next
) != NULL
) {
525 TRACE(("poplocalvar %s\n", vp
? vp
->text
: "-"));
526 if (vp
== NULL
) { /* $- saved */
527 memcpy(optlist
, lvp
->text
, sizeof(optlist
));
530 } else if (lvp
->flags
== VUNSET
) {
531 vp
->flags
&= ~(VSTRFIXED
|VREADONLY
);
534 if ((vp
->flags
& (VTEXTFIXED
|VSTACK
)) == 0)
536 vp
->flags
= lvp
->flags
;
537 vp
->text
= lvp
->text
;
538 if (vp
->func
&& !(vp
->flags
& VNOFUNC
))
539 (*vp
->func
)(varnull(vp
->text
));
548 * Create a new localvar environment.
550 struct localvar_list
*pushlocalvars(int push
)
552 struct localvar_list
*ll
;
553 struct localvar_list
*top
;
555 top
= localvar_stack
;
560 ll
= ckmalloc(sizeof(*ll
));
571 void unwindlocalvars(struct localvar_list
*stop
)
573 while (localvar_stack
!= stop
)
579 * The unset builtin command. We unset the function before we unset the
580 * variable to allow a function to be unset when there is a readonly variable
581 * with the same name.
585 unsetcmd(int argc
, char **argv
)
591 while ((i
= nextopt("vf")) != '\0') {
595 for (ap
= argptr
; *ap
; ap
++) {
608 * Unset the specified variable.
611 void unsetvar(const char *s
)
619 * Find the appropriate entry in the hash table from the name.
623 hashvar(const char *p
)
625 return &vartab
[hashval(p
) % VTABSIZE
];
631 * Compares two strings up to the first = or '\0'. The first
632 * string must be terminated by '='; the second may be terminated by
633 * either '=' or '\0'.
637 varcmp(const char *p
, const char *q
)
656 vpcmp(const void *a
, const void *b
)
658 return varcmp(*(const char **)a
, *(const char **)b
);
662 findvar(const char *name
)
666 for (vpp
= hashvar(name
); *vpp
; vpp
= &(*vpp
)->next
) {
667 if (varequal((*vpp
)->text
, name
)) {