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} |