exec.c
来自「Android 一些工具」· C语言 代码 · 共 1,064 行 · 第 1/2 页
C
1,064 行
} while (stat(fullname, &statb) < 0) {#ifdef SYSV if (errno == EINTR) continue;#endif if (errno != ENOENT && errno != ENOTDIR) e = errno; goto loop; } e = EACCES; /* if we fail, this will be the error */ if (!S_ISREG(statb.st_mode)) goto loop; if (pathopt) { /* this is a %func directory */ if (act & DO_NOFUNC) goto loop; stalloc(strlen(fullname) + 1); readcmdfile(fullname); if ((cmdp = cmdlookup(name, 0)) == NULL || cmdp->cmdtype != CMDFUNCTION) error("%s not defined in %s", name, fullname); stunalloc(fullname); goto success; }#ifdef notdef /* XXX this code stops root executing stuff, and is buggy if you need a group from the group list. */ if (statb.st_uid == geteuid()) { if ((statb.st_mode & 0100) == 0) goto loop; } else if (statb.st_gid == getegid()) { if ((statb.st_mode & 010) == 0) goto loop; } else { if ((statb.st_mode & 01) == 0) goto loop; }#endif TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname)); INTOFF; if (act & DO_ALTPATH) { stalloc(strlen(fullname) + 1); cmdp = &loc_cmd; } else cmdp = cmdlookup(name, 1); cmdp->cmdtype = CMDNORMAL; cmdp->param.index = idx; INTON; goto success; } /* We failed. If there was an entry for this command, delete it */ if (cmdp) delete_cmd_entry(); if (act & DO_ERR) outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC)); entry->cmdtype = CMDUNKNOWN; return;builtin_success: INTOFF; if (act & DO_ALTPATH) cmdp = &loc_cmd; else cmdp = cmdlookup(name, 1); if (cmdp->cmdtype == CMDFUNCTION) /* DO_NOFUNC must have been set */ cmdp = &loc_cmd; cmdp->cmdtype = CMDBUILTIN; cmdp->param.bltin = bltin; INTON;success: cmdp->rehash = 0; entry->cmdtype = cmdp->cmdtype; entry->u = cmdp->param;}/* * Search the table of builtin commands. */int(*find_builtin(name))(int, char **) char *name;{ const struct builtincmd *bp; for (bp = builtincmd ; bp->name ; bp++) { if (*bp->name == *name && equal(bp->name, name)) return bp->builtin; } return 0;}int(*find_splbltin(name))(int, char **) char *name;{ const struct builtincmd *bp; for (bp = splbltincmd ; bp->name ; bp++) { if (*bp->name == *name && equal(bp->name, name)) return bp->builtin; } return 0;}/* * At shell startup put special builtins into hash table. * ensures they are executed first (see posix). * We stop functions being added with the same name * (as they are impossible to call) */voidhash_special_builtins(void){ const struct builtincmd *bp; struct tblentry *cmdp; for (bp = splbltincmd ; bp->name ; bp++) { cmdp = cmdlookup(bp->name, 1); cmdp->cmdtype = CMDSPLBLTIN; cmdp->param.bltin = bp->builtin; }}/* * Called when a cd is done. Marks all commands so the next time they * are executed they will be rehashed. */voidhashcd(void){ struct tblentry **pp; struct tblentry *cmdp; for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) { for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) { if (cmdp->cmdtype == CMDNORMAL || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)) cmdp->rehash = 1; } }}/* * Fix command hash table when PATH changed. * Called before PATH is changed. The argument is the new value of PATH; * pathval() still returns the old value at this point. * Called with interrupts off. */voidchangepath(const char *newval){ const char *old, *new; int idx; int firstchange; int bltin; old = pathval(); new = newval; firstchange = 9999; /* assume no change */ idx = 0; bltin = -1; for (;;) { if (*old != *new) { firstchange = idx; if ((*old == '\0' && *new == ':') || (*old == ':' && *new == '\0')) firstchange++; old = new; /* ignore subsequent differences */ } if (*new == '\0') break; if (*new == '%' && bltin < 0 && prefix("builtin", new + 1)) bltin = idx; if (*new == ':') { idx++; } new++, old++; } if (builtinloc < 0 && bltin >= 0) builtinloc = bltin; /* zap builtins */ if (builtinloc >= 0 && bltin < 0) firstchange = 0; clearcmdentry(firstchange); builtinloc = bltin;}/* * Clear out command entries. The argument specifies the first entry in * PATH which has changed. */STATIC voidclearcmdentry(int firstchange){ struct tblentry **tblp; struct tblentry **pp; struct tblentry *cmdp; INTOFF; for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) { pp = tblp; while ((cmdp = *pp) != NULL) { if ((cmdp->cmdtype == CMDNORMAL && cmdp->param.index >= firstchange) || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= firstchange)) { *pp = cmdp->next; ckfree(cmdp); } else { pp = &cmdp->next; } } } INTON;}/* * Delete all functions. */#ifdef mkinitMKINIT void deletefuncs(void);MKINIT void hash_special_builtins(void);INIT { hash_special_builtins();}SHELLPROC { deletefuncs();}#endifvoiddeletefuncs(void){ struct tblentry **tblp; struct tblentry **pp; struct tblentry *cmdp; INTOFF; for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) { pp = tblp; while ((cmdp = *pp) != NULL) { if (cmdp->cmdtype == CMDFUNCTION) { *pp = cmdp->next; freefunc(cmdp->param.func); ckfree(cmdp); } else { pp = &cmdp->next; } } } INTON;}/* * Locate a command in the command hash table. If "add" is nonzero, * add the command to the table if it is not already present. The * variable "lastcmdentry" is set to point to the address of the link * pointing to the entry, so that delete_cmd_entry can delete the * entry. */struct tblentry **lastcmdentry;STATIC struct tblentry *cmdlookup(const char *name, int add){ int hashval; const char *p; struct tblentry *cmdp; struct tblentry **pp; p = name; hashval = *p << 4; while (*p) hashval += *p++; hashval &= 0x7FFF; pp = &cmdtable[hashval % CMDTABLESIZE]; for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) { if (equal(cmdp->cmdname, name)) break; pp = &cmdp->next; } if (add && cmdp == NULL) { INTOFF; cmdp = *pp = ckmalloc(sizeof (struct tblentry) - ARB + strlen(name) + 1); cmdp->next = NULL; cmdp->cmdtype = CMDUNKNOWN; cmdp->rehash = 0; strcpy(cmdp->cmdname, name); INTON; } lastcmdentry = pp; return cmdp;}/* * Delete the command entry returned on the last lookup. */STATIC voiddelete_cmd_entry(void){ struct tblentry *cmdp; INTOFF; cmdp = *lastcmdentry; *lastcmdentry = cmdp->next; ckfree(cmdp); INTON;}#ifdef notdefvoidgetcmdentry(char *name, struct cmdentry *entry){ struct tblentry *cmdp = cmdlookup(name, 0); if (cmdp) { entry->u = cmdp->param; entry->cmdtype = cmdp->cmdtype; } else { entry->cmdtype = CMDUNKNOWN; entry->u.index = 0; }}#endif/* * Add a new command entry, replacing any existing command entry for * the same name - except special builtins. */STATIC voidaddcmdentry(char *name, struct cmdentry *entry){ struct tblentry *cmdp; INTOFF; cmdp = cmdlookup(name, 1); if (cmdp->cmdtype != CMDSPLBLTIN) { if (cmdp->cmdtype == CMDFUNCTION) { freefunc(cmdp->param.func); } cmdp->cmdtype = entry->cmdtype; cmdp->param = entry->u; } INTON;}/* * Define a shell function. */voiddefun(char *name, union node *func){ struct cmdentry entry; INTOFF; entry.cmdtype = CMDFUNCTION; entry.u.func = copyfunc(func); addcmdentry(name, &entry); INTON;}/* * Delete a function if it exists. */intunsetfunc(char *name){ struct tblentry *cmdp; if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) { freefunc(cmdp->param.func); delete_cmd_entry(); return (0); } return (1);}/* * Locate and print what a word is... * also used for 'command -[v|V]' */inttypecmd(int argc, char **argv){ struct cmdentry entry; struct tblentry *cmdp; char * const *pp; struct alias *ap; int err = 0; char *arg; int c; int V_flag = 0; int v_flag = 0; int p_flag = 0; while ((c = nextopt("vVp")) != 0) { switch (c) { case 'v': v_flag = 1; break; case 'V': V_flag = 1; break; case 'p': p_flag = 1; break; } } if (p_flag && (v_flag || V_flag)) error("cannot specify -p with -v or -V"); while ((arg = *argptr++)) { if (!v_flag) out1str(arg); /* First look at the keywords */ for (pp = parsekwd; *pp; pp++) if (**pp == *arg && equal(*pp, arg)) break; if (*pp) { if (v_flag) err = 1; else out1str(" is a shell keyword\n"); continue; } /* Then look at the aliases */ if ((ap = lookupalias(arg, 1)) != NULL) { if (!v_flag) out1fmt(" is an alias for \n"); out1fmt("%s\n", ap->val); continue; } /* Then check if it is a tracked alias */ if ((cmdp = cmdlookup(arg, 0)) != NULL) { entry.cmdtype = cmdp->cmdtype; entry.u = cmdp->param; } else { /* Finally use brute force */ find_command(arg, &entry, DO_ABS, pathval()); } switch (entry.cmdtype) { case CMDNORMAL: { if (strchr(arg, '/') == NULL) { const char *path = pathval(); char *name; int j = entry.u.index; do { name = padvance(&path, arg); stunalloc(name); } while (--j >= 0); if (!v_flag) out1fmt(" is%s ", cmdp ? " a tracked alias for" : ""); out1fmt("%s\n", name); } else { if (access(arg, X_OK) == 0) { if (!v_flag) out1fmt(" is "); out1fmt("%s\n", arg); } else { if (!v_flag) out1fmt(": %s\n", strerror(errno)); else err = 126; } } break; } case CMDFUNCTION: if (!v_flag) out1str(" is a shell function\n"); else out1fmt("%s\n", arg); break; case CMDBUILTIN: if (!v_flag) out1str(" is a shell builtin\n"); else out1fmt("%s\n", arg); break; case CMDSPLBLTIN: if (!v_flag) out1str(" is a special shell builtin\n"); else out1fmt("%s\n", arg); break; default: if (!v_flag) out1str(": not found\n"); err = 127; break; } } return err;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?