var.c
来自「Android 一些工具」· C语言 代码 · 共 826 行 · 第 1/2 页
C
826 行
/* $NetBSD: var.c,v 1.36 2004/10/06 10:23:43 enami Exp $ *//*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Kenneth Almquist. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include <sys/cdefs.h>#ifndef lint#if 0static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95";#else__RCSID("$NetBSD: var.c,v 1.36 2004/10/06 10:23:43 enami Exp $");#endif#endif /* not lint */#include <unistd.h>#include <stdlib.h>#include <paths.h>/* * Shell variables. */#include "shell.h"#include "output.h"#include "expand.h"#include "nodes.h" /* for other headers */#include "eval.h" /* defines cmdenviron */#include "exec.h"#include "syntax.h"#include "options.h"#include "var.h"#include "memalloc.h"#include "error.h"#include "mystring.h"#include "parser.h"#include "show.h"#ifndef SMALL#include "myhistedit.h"#endif#ifdef SMALL#define VTABSIZE 39#else#define VTABSIZE 517#endifstruct varinit { struct var *var; int flags; const char *text; void (*func)(const char *);};#if ATTYstruct var vatty;#endif#ifdef WITH_HISTORYstruct var vhistsize;struct var vterm;#endifstruct var vifs;struct var vmpath;struct var vpath;struct var vps1;struct var vps2;struct var vps4;struct var vvers;struct var voptind;const struct varinit varinit[] = {#if ATTY { &vatty, VSTRFIXED|VTEXTFIXED|VUNSET, "ATTY=", NULL },#endif#ifdef WITH_HISTORY { &vhistsize, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTSIZE=", sethistsize },#endif { &vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n", NULL }, { &vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH=", NULL }, { &vpath, VSTRFIXED|VTEXTFIXED, "PATH=" _PATH_DEFPATH, changepath }, /* * vps1 depends on uid */ { &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ", NULL }, { &vps4, VSTRFIXED|VTEXTFIXED, "PS4=+ ", NULL },#ifdef WITH_HISTORY { &vterm, VSTRFIXED|VTEXTFIXED|VUNSET, "TERM=", setterm },#endif { &voptind, VSTRFIXED|VTEXTFIXED|VNOFUNC, "OPTIND=1", getoptsreset }, { NULL, 0, NULL, NULL }};struct var *vartab[VTABSIZE];STATIC int strequal(const char *, const char *);STATIC struct var *find_var(const char *, struct var ***, int *);/* * Initialize the varable symbol tables and import the environment */#ifdef mkinitINCLUDE "var.h"MKINIT char **environ;INIT { char **envp; initvar(); for (envp = environ ; *envp ; envp++) { if (strchr(*envp, '=')) { setvareq(*envp, VEXPORT|VTEXTFIXED); } }}#endif/* * This routine initializes the builtin variables. It is called when the * shell is initialized and again when a shell procedure is spawned. */voidinitvar(void){ const struct varinit *ip; struct var *vp; struct var **vpp; for (ip = varinit ; (vp = ip->var) != NULL ; ip++) { if (find_var(ip->text, &vpp, &vp->name_len) != NULL) continue; vp->next = *vpp; *vpp = vp; vp->text = strdup(ip->text); vp->flags = ip->flags; vp->func = ip->func; } /* * PS1 depends on uid */ if (find_var("PS1", &vpp, &vps1.name_len) == NULL) { vps1.next = *vpp; *vpp = &vps1; vps1.text = strdup(geteuid() ? "PS1=$ " : "PS1=# "); vps1.flags = VSTRFIXED|VTEXTFIXED; }}/* * Safe version of setvar, returns 1 on success 0 on failure. */intsetvarsafe(const char *name, const char *val, int flags){ struct jmploc jmploc; struct jmploc *volatile savehandler = handler; int err = 0;#ifdef __GNUC__ (void) &err;#endif if (setjmp(jmploc.loc)) err = 1; else { handler = &jmploc; setvar(name, val, flags); } handler = savehandler; return err;}/* * Set the value of a variable. The flags argument is ored with the * flags of the variable. If val is NULL, the variable is unset. */voidsetvar(const char *name, const char *val, int flags){ const char *p; const char *q; char *d; int len; int namelen; char *nameeq; int isbad; isbad = 0; p = name; if (! is_name(*p)) isbad = 1; p++; for (;;) { if (! is_in_name(*p)) { if (*p == '\0' || *p == '=') break; isbad = 1; } p++; } namelen = p - name; if (isbad) error("%.*s: bad variable name", namelen, name); len = namelen + 2; /* 2 is space for '=' and '\0' */ if (val == NULL) { flags |= VUNSET; } else { len += strlen(val); } d = nameeq = ckmalloc(len); q = name; while (--namelen >= 0) *d++ = *q++; *d++ = '='; *d = '\0'; if (val) scopy(val, d); setvareq(nameeq, flags);}/* * Same as setvar except that the variable and value are passed in * the first argument as name=value. Since the first argument will * be actually stored in the table, it should not be a string that * will go away. */voidsetvareq(char *s, int flags){ struct var *vp, **vpp; int nlen; if (aflag) flags |= VEXPORT; vp = find_var(s, &vpp, &nlen); if (vp != NULL) { if (vp->flags & VREADONLY) error("%.*s: is read only", vp->name_len, s); if (flags & VNOSET) return; INTOFF; if (vp->func && (flags & VNOFUNC) == 0) (*vp->func)(s + vp->name_len + 1); if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) ckfree(vp->text); vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET); vp->flags |= flags & ~VNOFUNC; vp->text = s; INTON; return; } /* not found */ if (flags & VNOSET) return; vp = ckmalloc(sizeof (*vp)); vp->flags = flags & ~VNOFUNC; vp->text = s; vp->name_len = nlen; vp->next = *vpp; vp->func = NULL; *vpp = vp;}/* * Process a linked list of variable assignments. */voidlistsetvar(struct strlist *list, int flags){ struct strlist *lp; INTOFF; for (lp = list ; lp ; lp = lp->next) { setvareq(savestr(lp->text), flags); } INTON;}voidlistmklocal(struct strlist *list, int flags){ struct strlist *lp; for (lp = list ; lp ; lp = lp->next) mklocal(lp->text, flags);}/* * Find the value of a variable. Returns NULL if not set. */char *lookupvar(const char *name){ struct var *v; v = find_var(name, NULL, NULL); if (v == NULL || v->flags & VUNSET) return NULL; return v->text + v->name_len + 1;}/* * Search the environment of a builtin command. If the second argument * is nonzero, return the value of a variable even if it hasn't been * exported. */char *bltinlookup(const char *name, int doall){ struct strlist *sp; struct var *v; for (sp = cmdenviron ; sp ; sp = sp->next) { if (strequal(sp->text, name)) return strchr(sp->text, '=') + 1; } v = find_var(name, NULL, NULL); if (v == NULL || v->flags & VUNSET || (!doall && !(v->flags & VEXPORT))) return NULL; return v->text + v->name_len + 1;}/* * Generate a list of exported variables. This routine is used to construct * the third argument to execve when executing a program. */char **environment(void){ int nenv; struct var **vpp; struct var *vp; char **env; char **ep; nenv = 0; for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { for (vp = *vpp ; vp ; vp = vp->next) if (vp->flags & VEXPORT) nenv++; } ep = env = stalloc((nenv + 1) * sizeof *env); for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { for (vp = *vpp ; vp ; vp = vp->next) if (vp->flags & VEXPORT) *ep++ = vp->text; } *ep = NULL; return env;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?