Deleted Added
full compact
var.c (50471) var.c (90111)
1/*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kenneth Almquist.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 25 unchanged lines hidden (view full) ---

34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38#if 0
39static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95";
40#endif
41static const char rcsid[] =
1/*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kenneth Almquist.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 25 unchanged lines hidden (view full) ---

34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38#if 0
39static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95";
40#endif
41static const char rcsid[] =
42 "$FreeBSD: head/bin/sh/var.c 50471 1999-08-27 23:15:48Z peter $";
42 "$FreeBSD: head/bin/sh/var.c 90111 2002-02-02 06:50:57Z imp $";
43#endif /* not lint */
44
45#include <unistd.h>
46#include <stdlib.h>
47
48/*
49 * Shell variables.
50 */

--- 21 unchanged lines hidden (view full) ---

72
73#define VTABSIZE 39
74
75
76struct varinit {
77 struct var *var;
78 int flags;
79 char *text;
43#endif /* not lint */
44
45#include <unistd.h>
46#include <stdlib.h>
47
48/*
49 * Shell variables.
50 */

--- 21 unchanged lines hidden (view full) ---

72
73#define VTABSIZE 39
74
75
76struct varinit {
77 struct var *var;
78 int flags;
79 char *text;
80 void (*func) __P((const char *));
80 void (*func)(const char *);
81};
82
83
84#if ATTY
85struct var vatty;
86#endif
87#ifndef NO_HISTORY
88struct var vhistsize;

--- 39 unchanged lines hidden (view full) ---

128 { &voptind, VSTRFIXED|VTEXTFIXED, "OPTIND=1",
129 getoptsreset },
130 { NULL, 0, NULL,
131 NULL }
132};
133
134struct var *vartab[VTABSIZE];
135
81};
82
83
84#if ATTY
85struct var vatty;
86#endif
87#ifndef NO_HISTORY
88struct var vhistsize;

--- 39 unchanged lines hidden (view full) ---

128 { &voptind, VSTRFIXED|VTEXTFIXED, "OPTIND=1",
129 getoptsreset },
130 { NULL, 0, NULL,
131 NULL }
132};
133
134struct var *vartab[VTABSIZE];
135
136STATIC struct var **hashvar __P((char *));
137STATIC int varequal __P((char *, char *));
138STATIC int localevar __P((char *));
136STATIC struct var **hashvar(char *);
137STATIC int varequal(char *, char *);
138STATIC int localevar(char *);
139
140/*
141 * Initialize the varable symbol tables and import the environment
142 */
143
144#ifdef mkinit
145INCLUDE "var.h"
146INIT {

--- 11 unchanged lines hidden (view full) ---

158
159
160/*
161 * This routine initializes the builtin variables. It is called when the
162 * shell is initialized and again when a shell procedure is spawned.
163 */
164
165void
139
140/*
141 * Initialize the varable symbol tables and import the environment
142 */
143
144#ifdef mkinit
145INCLUDE "var.h"
146INIT {

--- 11 unchanged lines hidden (view full) ---

158
159
160/*
161 * This routine initializes the builtin variables. It is called when the
162 * shell is initialized and again when a shell procedure is spawned.
163 */
164
165void
166initvar() {
166initvar(void)
167{
167 const struct varinit *ip;
168 struct var *vp;
169 struct var **vpp;
170
171 for (ip = varinit ; (vp = ip->var) != NULL ; ip++) {
172 if ((vp->flags & VEXPORT) == 0) {
173 vpp = hashvar(ip->text);
174 vp->next = *vpp;

--- 15 unchanged lines hidden (view full) ---

190 }
191}
192
193/*
194 * Safe version of setvar, returns 1 on success 0 on failure.
195 */
196
197int
168 const struct varinit *ip;
169 struct var *vp;
170 struct var **vpp;
171
172 for (ip = varinit ; (vp = ip->var) != NULL ; ip++) {
173 if ((vp->flags & VEXPORT) == 0) {
174 vpp = hashvar(ip->text);
175 vp->next = *vpp;

--- 15 unchanged lines hidden (view full) ---

191 }
192}
193
194/*
195 * Safe version of setvar, returns 1 on success 0 on failure.
196 */
197
198int
198setvarsafe(name, val, flags)
199 char *name, *val;
200 int flags;
199setvarsafe(char *name, char *val, int flags)
201{
202 struct jmploc jmploc;
203 struct jmploc *volatile savehandler = handler;
204 int err = 0;
205#if __GNUC__
206 /* Avoid longjmp clobbering */
207 (void) &err;
208#endif

--- 9 unchanged lines hidden (view full) ---

218}
219
220/*
221 * Set the value of a variable. The flags argument is tored with the
222 * flags of the variable. If val is NULL, the variable is unset.
223 */
224
225void
200{
201 struct jmploc jmploc;
202 struct jmploc *volatile savehandler = handler;
203 int err = 0;
204#if __GNUC__
205 /* Avoid longjmp clobbering */
206 (void) &err;
207#endif

--- 9 unchanged lines hidden (view full) ---

217}
218
219/*
220 * Set the value of a variable. The flags argument is tored with the
221 * flags of the variable. If val is NULL, the variable is unset.
222 */
223
224void
226setvar(name, val, flags)
227 char *name, *val;
228 int flags;
225setvar(char *name, char *val, int flags)
229{
230 char *p, *q;
231 int len;
232 int namelen;
233 char *nameeq;
234 int isbad;
235
236 isbad = 0;

--- 25 unchanged lines hidden (view full) ---

262 *p++ = '=';
263 *p = '\0';
264 if (val)
265 scopy(val, p);
266 setvareq(nameeq, flags);
267}
268
269STATIC int
226{
227 char *p, *q;
228 int len;
229 int namelen;
230 char *nameeq;
231 int isbad;
232
233 isbad = 0;

--- 25 unchanged lines hidden (view full) ---

259 *p++ = '=';
260 *p = '\0';
261 if (val)
262 scopy(val, p);
263 setvareq(nameeq, flags);
264}
265
266STATIC int
270localevar(s)
271 char *s;
272 {
267localevar(char *s)
268{
273 static char *lnames[7] = {
274 "ALL", "COLLATE", "CTYPE", "MONETARY",
275 "NUMERIC", "TIME", NULL
276 };
277 char **ss;
278
279 if (*s != 'L')
280 return 0;

--- 10 unchanged lines hidden (view full) ---

291/*
292 * Same as setvar except that the variable and value are passed in
293 * the first argument as name=value. Since the first argument will
294 * be actually stored in the table, it should not be a string that
295 * will go away.
296 */
297
298void
269 static char *lnames[7] = {
270 "ALL", "COLLATE", "CTYPE", "MONETARY",
271 "NUMERIC", "TIME", NULL
272 };
273 char **ss;
274
275 if (*s != 'L')
276 return 0;

--- 10 unchanged lines hidden (view full) ---

287/*
288 * Same as setvar except that the variable and value are passed in
289 * the first argument as name=value. Since the first argument will
290 * be actually stored in the table, it should not be a string that
291 * will go away.
292 */
293
294void
299setvareq(s, flags)
300 char *s;
301 int flags;
295setvareq(char *s, int flags)
302{
303 struct var *vp, **vpp;
304
305 if (aflag)
306 flags |= VEXPORT;
307 vpp = hashvar(s);
308 for (vp = *vpp ; vp ; vp = vp->next) {
309 if (varequal(s, vp->text)) {

--- 44 unchanged lines hidden (view full) ---

354
355
356
357/*
358 * Process a linked list of variable assignments.
359 */
360
361void
296{
297 struct var *vp, **vpp;
298
299 if (aflag)
300 flags |= VEXPORT;
301 vpp = hashvar(s);
302 for (vp = *vpp ; vp ; vp = vp->next) {
303 if (varequal(s, vp->text)) {

--- 44 unchanged lines hidden (view full) ---

348
349
350
351/*
352 * Process a linked list of variable assignments.
353 */
354
355void
362listsetvar(list)
363 struct strlist *list;
364 {
356listsetvar(struct strlist *list)
357{
365 struct strlist *lp;
366
367 INTOFF;
368 for (lp = list ; lp ; lp = lp->next) {
369 setvareq(savestr(lp->text), 0);
370 }
371 INTON;
372}
373
374
375
376/*
377 * Find the value of a variable. Returns NULL if not set.
378 */
379
380char *
358 struct strlist *lp;
359
360 INTOFF;
361 for (lp = list ; lp ; lp = lp->next) {
362 setvareq(savestr(lp->text), 0);
363 }
364 INTON;
365}
366
367
368
369/*
370 * Find the value of a variable. Returns NULL if not set.
371 */
372
373char *
381lookupvar(name)
382 char *name;
383 {
374lookupvar(char *name)
375{
384 struct var *v;
385
386 for (v = *hashvar(name) ; v ; v = v->next) {
387 if (varequal(v->text, name)) {
388 if (v->flags & VUNSET)
389 return NULL;
390 return strchr(v->text, '=') + 1;
391 }

--- 5 unchanged lines hidden (view full) ---

397
398/*
399 * Search the environment of a builtin command. If the second argument
400 * is nonzero, return the value of a variable even if it hasn't been
401 * exported.
402 */
403
404char *
376 struct var *v;
377
378 for (v = *hashvar(name) ; v ; v = v->next) {
379 if (varequal(v->text, name)) {
380 if (v->flags & VUNSET)
381 return NULL;
382 return strchr(v->text, '=') + 1;
383 }

--- 5 unchanged lines hidden (view full) ---

389
390/*
391 * Search the environment of a builtin command. If the second argument
392 * is nonzero, return the value of a variable even if it hasn't been
393 * exported.
394 */
395
396char *
405bltinlookup(name, doall)
406 char *name;
407 int doall;
397bltinlookup(char *name, int doall)
408{
409 struct strlist *sp;
410 struct var *v;
411
412 for (sp = cmdenviron ; sp ; sp = sp->next) {
413 if (varequal(sp->text, name))
414 return strchr(sp->text, '=') + 1;
415 }

--- 11 unchanged lines hidden (view full) ---

427
428
429/*
430 * Generate a list of exported variables. This routine is used to construct
431 * the third argument to execve when executing a program.
432 */
433
434char **
398{
399 struct strlist *sp;
400 struct var *v;
401
402 for (sp = cmdenviron ; sp ; sp = sp->next) {
403 if (varequal(sp->text, name))
404 return strchr(sp->text, '=') + 1;
405 }

--- 11 unchanged lines hidden (view full) ---

417
418
419/*
420 * Generate a list of exported variables. This routine is used to construct
421 * the third argument to execve when executing a program.
422 */
423
424char **
435environment() {
425environment(void)
426{
436 int nenv;
437 struct var **vpp;
438 struct var *vp;
439 char **env, **ep;
440
441 nenv = 0;
442 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
443 for (vp = *vpp ; vp ; vp = vp->next)

--- 21 unchanged lines hidden (view full) ---

465MKINIT void shprocvar();
466
467SHELLPROC {
468 shprocvar();
469}
470#endif
471
472void
427 int nenv;
428 struct var **vpp;
429 struct var *vp;
430 char **env, **ep;
431
432 nenv = 0;
433 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
434 for (vp = *vpp ; vp ; vp = vp->next)

--- 21 unchanged lines hidden (view full) ---

456MKINIT void shprocvar();
457
458SHELLPROC {
459 shprocvar();
460}
461#endif
462
463void
473shprocvar() {
464shprocvar(void)
465{
474 struct var **vpp;
475 struct var *vp, **prev;
476
477 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
478 for (prev = vpp ; (vp = *prev) != NULL ; ) {
479 if ((vp->flags & VEXPORT) == 0) {
480 *prev = vp->next;
481 if ((vp->flags & VTEXTFIXED) == 0)

--- 16 unchanged lines hidden (view full) ---

498
499/*
500 * Command to list all variables which are set. Currently this command
501 * is invoked from the set command when the set command is called without
502 * any variables.
503 */
504
505int
466 struct var **vpp;
467 struct var *vp, **prev;
468
469 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
470 for (prev = vpp ; (vp = *prev) != NULL ; ) {
471 if ((vp->flags & VEXPORT) == 0) {
472 *prev = vp->next;
473 if ((vp->flags & VTEXTFIXED) == 0)

--- 16 unchanged lines hidden (view full) ---

490
491/*
492 * Command to list all variables which are set. Currently this command
493 * is invoked from the set command when the set command is called without
494 * any variables.
495 */
496
497int
506showvarscmd(argc, argv)
507 int argc __unused;
508 char **argv __unused;
498showvarscmd(int argc __unused, char **argv __unused)
509{
510 struct var **vpp;
511 struct var *vp;
512
513 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
514 for (vp = *vpp ; vp ; vp = vp->next) {
515 if ((vp->flags & VUNSET) == 0)
516 out1fmt("%s\n", vp->text);

--- 4 unchanged lines hidden (view full) ---

521
522
523
524/*
525 * The export and readonly commands.
526 */
527
528int
499{
500 struct var **vpp;
501 struct var *vp;
502
503 for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
504 for (vp = *vpp ; vp ; vp = vp->next) {
505 if ((vp->flags & VUNSET) == 0)
506 out1fmt("%s\n", vp->text);

--- 4 unchanged lines hidden (view full) ---

511
512
513
514/*
515 * The export and readonly commands.
516 */
517
518int
529exportcmd(argc, argv)
530 int argc;
531 char **argv;
519exportcmd(int argc, char **argv)
532{
533 struct var **vpp;
534 struct var *vp;
535 char *name;
536 char *p;
537 int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
538
539 listsetvar(cmdenviron);
540 if (argc > 1) {
541 while ((name = *argptr++) != NULL) {
542 if ((p = strchr(name, '=')) != NULL) {
543 p++;
544 } else {
545 vpp = hashvar(name);
546 for (vp = *vpp ; vp ; vp = vp->next) {
547 if (varequal(vp->text, name)) {
520{
521 struct var **vpp;
522 struct var *vp;
523 char *name;
524 char *p;
525 int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
526
527 listsetvar(cmdenviron);
528 if (argc > 1) {
529 while ((name = *argptr++) != NULL) {
530 if ((p = strchr(name, '=')) != NULL) {
531 p++;
532 } else {
533 vpp = hashvar(name);
534 for (vp = *vpp ; vp ; vp = vp->next) {
535 if (varequal(vp->text, name)) {
536
548 vp->flags |= flag;
549 if ((vp->flags & VEXPORT) && localevar(vp->text)) {
550 putenv(vp->text);
551 (void) setlocale(LC_ALL, "");
552 }
553 goto found;
554 }
555 }

--- 16 unchanged lines hidden (view full) ---

572}
573
574
575/*
576 * The "local" command.
577 */
578
579int
537 vp->flags |= flag;
538 if ((vp->flags & VEXPORT) && localevar(vp->text)) {
539 putenv(vp->text);
540 (void) setlocale(LC_ALL, "");
541 }
542 goto found;
543 }
544 }

--- 16 unchanged lines hidden (view full) ---

561}
562
563
564/*
565 * The "local" command.
566 */
567
568int
580localcmd(argc, argv)
581 int argc __unused;
582 char **argv __unused;
569localcmd(int argc __unused, char **argv __unused)
583{
584 char *name;
585
586 if (! in_function())
587 error("Not in a function");
588 while ((name = *argptr++) != NULL) {
589 mklocal(name);
590 }

--- 4 unchanged lines hidden (view full) ---

595/*
596 * Make a variable a local variable. When a variable is made local, it's
597 * value and flags are saved in a localvar structure. The saved values
598 * will be restored when the shell function returns. We handle the name
599 * "-" as a special case.
600 */
601
602void
570{
571 char *name;
572
573 if (! in_function())
574 error("Not in a function");
575 while ((name = *argptr++) != NULL) {
576 mklocal(name);
577 }

--- 4 unchanged lines hidden (view full) ---

582/*
583 * Make a variable a local variable. When a variable is made local, it's
584 * value and flags are saved in a localvar structure. The saved values
585 * will be restored when the shell function returns. We handle the name
586 * "-" as a special case.
587 */
588
589void
603mklocal(name)
604 char *name;
605 {
590mklocal(char *name)
591{
606 struct localvar *lvp;
607 struct var **vpp;
608 struct var *vp;
609
610 INTOFF;
611 lvp = ckmalloc(sizeof (struct localvar));
612 if (name[0] == '-' && name[1] == '\0') {
613 lvp->text = ckmalloc(sizeof optlist);

--- 25 unchanged lines hidden (view full) ---

639}
640
641
642/*
643 * Called after a function returns.
644 */
645
646void
592 struct localvar *lvp;
593 struct var **vpp;
594 struct var *vp;
595
596 INTOFF;
597 lvp = ckmalloc(sizeof (struct localvar));
598 if (name[0] == '-' && name[1] == '\0') {
599 lvp->text = ckmalloc(sizeof optlist);

--- 25 unchanged lines hidden (view full) ---

625}
626
627
628/*
629 * Called after a function returns.
630 */
631
632void
647poplocalvars() {
633poplocalvars(void)
634{
648 struct localvar *lvp;
649 struct var *vp;
650
651 while ((lvp = localvars) != NULL) {
652 localvars = lvp->next;
653 vp = lvp->vp;
654 if (vp == NULL) { /* $- saved */
655 memcpy(optlist, lvp->text, sizeof optlist);

--- 7 unchanged lines hidden (view full) ---

663 vp->text = lvp->text;
664 }
665 ckfree(lvp);
666 }
667}
668
669
670int
635 struct localvar *lvp;
636 struct var *vp;
637
638 while ((lvp = localvars) != NULL) {
639 localvars = lvp->next;
640 vp = lvp->vp;
641 if (vp == NULL) { /* $- saved */
642 memcpy(optlist, lvp->text, sizeof optlist);

--- 7 unchanged lines hidden (view full) ---

650 vp->text = lvp->text;
651 }
652 ckfree(lvp);
653 }
654}
655
656
657int
671setvarcmd(argc, argv)
672 int argc;
673 char **argv;
658setvarcmd(int argc, char **argv)
674{
675 if (argc <= 2)
676 return unsetcmd(argc, argv);
677 else if (argc == 3)
678 setvar(argv[1], argv[2], 0);
679 else
680 error("List assignment not implemented");
681 return 0;
682}
683
684
685/*
686 * The unset builtin command. We unset the function before we unset the
687 * variable to allow a function to be unset when there is a readonly variable
688 * with the same name.
689 */
690
691int
659{
660 if (argc <= 2)
661 return unsetcmd(argc, argv);
662 else if (argc == 3)
663 setvar(argv[1], argv[2], 0);
664 else
665 error("List assignment not implemented");
666 return 0;
667}
668
669
670/*
671 * The unset builtin command. We unset the function before we unset the
672 * variable to allow a function to be unset when there is a readonly variable
673 * with the same name.
674 */
675
676int
692unsetcmd(argc, argv)
693 int argc __unused;
694 char **argv __unused;
677unsetcmd(int argc __unused, char **argv __unused)
695{
696 char **ap;
697 int i;
698 int flg_func = 0;
699 int flg_var = 0;
700 int ret = 0;
701
702 while ((i = nextopt("vf")) != '\0') {

--- 15 unchanged lines hidden (view full) ---

718}
719
720
721/*
722 * Unset the specified variable.
723 */
724
725int
678{
679 char **ap;
680 int i;
681 int flg_func = 0;
682 int flg_var = 0;
683 int ret = 0;
684
685 while ((i = nextopt("vf")) != '\0') {

--- 15 unchanged lines hidden (view full) ---

701}
702
703
704/*
705 * Unset the specified variable.
706 */
707
708int
726unsetvar(s)
727 char *s;
728 {
709unsetvar(char *s)
710{
729 struct var **vpp;
730 struct var *vp;
731
732 vpp = hashvar(s);
733 for (vp = *vpp ; vp ; vpp = &vp->next, vp = *vpp) {
734 if (varequal(vp->text, s)) {
735 if (vp->flags & VREADONLY)
736 return (1);

--- 22 unchanged lines hidden (view full) ---

759
760
761
762/*
763 * Find the appropriate entry in the hash table from the name.
764 */
765
766STATIC struct var **
711 struct var **vpp;
712 struct var *vp;
713
714 vpp = hashvar(s);
715 for (vp = *vpp ; vp ; vpp = &vp->next, vp = *vpp) {
716 if (varequal(vp->text, s)) {
717 if (vp->flags & VREADONLY)
718 return (1);

--- 22 unchanged lines hidden (view full) ---

741
742
743
744/*
745 * Find the appropriate entry in the hash table from the name.
746 */
747
748STATIC struct var **
767hashvar(p)
768 char *p;
769 {
749hashvar(char *p)
750{
770 unsigned int hashval;
771
772 hashval = ((unsigned char) *p) << 4;
773 while (*p && *p != '=')
774 hashval += (unsigned char) *p++;
775 return &vartab[hashval % VTABSIZE];
776}
777
778
779
780/*
781 * Returns true if the two strings specify the same varable. The first
782 * variable name is terminated by '='; the second may be terminated by
783 * either '=' or '\0'.
784 */
785
786STATIC int
751 unsigned int hashval;
752
753 hashval = ((unsigned char) *p) << 4;
754 while (*p && *p != '=')
755 hashval += (unsigned char) *p++;
756 return &vartab[hashval % VTABSIZE];
757}
758
759
760
761/*
762 * Returns true if the two strings specify the same varable. The first
763 * variable name is terminated by '='; the second may be terminated by
764 * either '=' or '\0'.
765 */
766
767STATIC int
787varequal(p, q)
788 char *p, *q;
789 {
768varequal(char *p, char *q)
769{
790 while (*p == *q++) {
791 if (*p++ == '=')
792 return 1;
793 }
794 if (*p == '=' && *(q - 1) == '\0')
795 return 1;
796 return 0;
797}
770 while (*p == *q++) {
771 if (*p++ == '=')
772 return 1;
773 }
774 if (*p == '=' && *(q - 1) == '\0')
775 return 1;
776 return 0;
777}