⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exec.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* If name is in the table, and not invalidated by cd, we're done */	if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0)		goto success;	/* If %builtin not in path, check for builtin next */	if (builtinloc < 0 && (i = find_builtin(name)) >= 0) {		INTOFF;		cmdp = cmdlookup(name, 1);		cmdp->cmdtype = CMDBUILTIN;		cmdp->param.index = i;		INTON;		goto success;	}	/* We have to search path. */	prev = -1;		/* where to start */	if (cmdp) {		/* doing a rehash */		if (cmdp->cmdtype == CMDBUILTIN)			prev = builtinloc;		else			prev = cmdp->param.index;	}	path = pathval();	e = ENOENT;	index = -1;loop:	while ((fullname = padvance(&path, name)) != NULL) {		stunalloc(fullname);		index++;		if (pathopt) {			if (prefix("builtin", pathopt)) {				if ((i = find_builtin(name)) < 0)					goto loop;				INTOFF;				cmdp = cmdlookup(name, 1);				cmdp->cmdtype = CMDBUILTIN;				cmdp->param.index = i;				INTON;				goto success;			} else if (prefix("func", pathopt)) {				/* handled below */			} else {				goto loop;	/* ignore unimplemented options */			}		}		/* if rehash, don't redo absolute path names */		if (fullname[0] == '/' && index <= prev) {			if (index < prev)				goto loop;			TRACE(("searchexec \"%s\": no change\n", name));			goto success;		}		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 ((statb.st_mode & S_IFMT) != S_IFREG)			goto loop;		if (pathopt) {		/* this is a %func directory */			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;		}		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 __minix_vmd || defined(BSD)			gid_t group_list[NGROUPS_MAX];			int ngroups, i;			ngroups = getgroups(NGROUPS_MAX, group_list);			for (i = 0; i < ngroups; i++) {				if (statb.st_gid == group_list[i]) break;			}			if (i < ngroups) {				if ((statb.st_mode & 010) == 0)					goto loop;			} else#endif			if ((statb.st_mode & 01) == 0)				goto loop;		}		TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));		INTOFF;		cmdp = cmdlookup(name, 1);		cmdp->cmdtype = CMDNORMAL;		cmdp->param.index = index;		INTON;		goto success;	}	/* We failed.  If there was an entry for this command, delete it */	if (cmdp)		delete_cmd_entry();	if (printerr)		outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC));	entry->cmdtype = CMDUNKNOWN;	return;success:	cmdp->rehash = 0;	entry->cmdtype = cmdp->cmdtype;	entry->u = cmdp->param;}/* * Search the table of builtin commands. */intfind_builtin(name)	char *name;	{	const register struct builtincmd *bp;	for (bp = builtincmd ; bp->name ; bp++) {		if (*bp->name == *name && equal(bp->name, name))			return bp->code;	}	return -1;}/* * Called when a cd is done.  Marks all commands so the next time they * are executed they will be rehashed. */voidhashcd() {	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;		}	}}/* * 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(newval)	char *newval;	{	char *old, *new;	int index;	int firstchange;	int bltin;	old = pathval();	new = newval;	firstchange = 9999;	/* assume no change */	index = 0;	bltin = -1;	for (;;) {		if (*old != *new) {			firstchange = index;			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 = index;		if (*new == ':') {			index++;		}		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(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();SHELLPROC {	deletefuncs();}#endifvoiddeletefuncs() {	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(name, add)	char *name;	{	int hashval;	register 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() {	struct tblentry *cmdp;	INTOFF;	cmdp = *lastcmdentry;	*lastcmdentry = cmdp->next;	ckfree(cmdp);	INTON;}#ifdef notdefvoidgetcmdentry(name, entry)	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. */voidaddcmdentry(name, entry)	char *name;	struct cmdentry *entry;	{	struct tblentry *cmdp;	INTOFF;	cmdp = cmdlookup(name, 1);	if (cmdp->cmdtype == CMDFUNCTION) {		freefunc(cmdp->param.func);	}	cmdp->cmdtype = entry->cmdtype;	cmdp->param = entry->u;	INTON;}/* * Define a shell function. */voiddefun(name, func)	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. */voidunsetfunc(name)	char *name;	{	struct tblentry *cmdp;	if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) {		freefunc(cmdp->param.func);		delete_cmd_entry();	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -