mksh/mksh.logging/exec.c
struct tbl *
findcom(const char *name, int flags)
{
	static struct tbl temp;
	uint32_t h = hash(name);
	struct tbl *tp = NULL, *tbi;
	/* insert if not found */
	unsigned char insert = Flag(FTRACKALL);
	/* for function autoloading */
	char *fpath;
	union mksh_cchack npath;

	if (vstrchr(name, '/')) {
		insert = 0;
		/* prevent FPATH search below */
		flags &= ~FC_FUNC;
		goto Search;
	}
	tbi = (flags & FC_BI) ? ktsearch(&builtins, name, h) : NULL;
	/*
	 * POSIX says special builtins first, then functions, then
	 * regular builtins, then search path...
	 */
	if ((flags & FC_SPECBI) && tbi && (tbi->flag & SPEC_BI))
		tp = tbi;
	if (!tp && (flags & FC_FUNC)) {
		tp = findfunc(name, h, false);
		if (tp && !(tp->flag & ISSET)) {
			if ((fpath = str_val(global("FPATH"))) == null) {
				tp->u.fpath = NULL;
				tp->u2.errnov = ENOENT;
			} else
				tp->u.fpath = search_path(name, fpath, R_OK,
				    &tp->u2.errnov);
		}
	}
	if (!tp && (flags & FC_NORMBI) && tbi)
		tp = tbi;
	if (!tp && (flags & FC_PATH) && !(flags & FC_DEFPATH)) {
		tp = ktsearch(&taliases, name, h);
		if (tp && (tp->flag & ISSET) &&
		    ksh_access(tp->val.s, X_OK) != 0) {
			if (tp->flag & ALLOC) {
				tp->flag &= ~ALLOC;
				afree(tp->val.s, APERM);
			}
			tp->flag &= ~ISSET;
		}
	}

 Search:
	if ((!tp || (tp->type == CTALIAS && !(tp->flag&ISSET))) &&
	    (flags & FC_PATH)) {
		if (!tp) {
			if (insert && !(flags & FC_DEFPATH)) {
				tp = ktenter(&taliases, name, h);
				tp->type = CTALIAS;
			} else {
				tp = &temp;
				tp->type = CEXEC;
			}
			/* make ~ISSET */
			tp->flag = DEFINED;
		}
		npath.ro = search_path(name,
		    (flags & FC_DEFPATH) ? def_path : path,
		    X_OK, &tp->u2.errnov);
		if (npath.ro) {
			strdupx(tp->val.s, npath.ro, APERM);
			if (npath.ro != name)
				afree(npath.rw, ATEMP);
			tp->flag |= ISSET|ALLOC;
		} else if ((flags & FC_FUNC) &&
		    (fpath = str_val(global("FPATH"))) != null &&
		    (npath.ro = search_path(name, fpath, R_OK,
		    &tp->u2.errnov)) != NULL) {
			/*
			 * An undocumented feature of AT&T ksh is that
			 * it searches FPATH if a command is not found,
			 * even if the command hasn't been set up as an
			 * autoloaded function (ie, no typeset -uf).
			 */
			tp = &temp;
			tp->type = CFUNC;
			/* make ~ISSET */
			tp->flag = DEFINED;
			tp->u.fpath = npath.ro;
		}
	}
	return (tp);
}
/*
 * find command
 * either function, hashed command, or built-in (in that order)
 */
find command
either function, hashed command, or built-in (in that order)
find command either function hashed command or built - in ( in that order )
struct tbl *
findcom(const char *name, int flags)
{
	static struct tbl temp;
	uint32_t h = hash(name);
	struct tbl *tp = NULL, *tbi;
	unsigned char insert = Flag(FTRACKALL);
	char *fpath;
	union mksh_cchack npath;
	if (vstrchr(name, '/')) {
		insert = 0;
		flags &= ~FC_FUNC;
		goto Search;
	}
	tbi = (flags & FC_BI) ? ktsearch(&builtins, name, h) : NULL;
	if ((flags & FC_SPECBI) && tbi && (tbi->flag & SPEC_BI))
		tp = tbi;
	if (!tp && (flags & FC_FUNC)) {
		tp = findfunc(name, h, false);
		if (tp && !(tp->flag & ISSET)) {
			if ((fpath = str_val(global("FPATH"))) == null) {
				tp->u.fpath = NULL;
				tp->u2.errnov = ENOENT;
			} else
				tp->u.fpath = search_path(name, fpath, R_OK,
				    &tp->u2.errnov);
		}
	}
	if (!tp && (flags & FC_NORMBI) && tbi)
		tp = tbi;
	if (!tp && (flags & FC_PATH) && !(flags & FC_DEFPATH)) {
		tp = ktsearch(&taliases, name, h);
		if (tp && (tp->flag & ISSET) &&
		    ksh_access(tp->val.s, X_OK) != 0) {
			if (tp->flag & ALLOC) {
				tp->flag &= ~ALLOC;
				afree(tp->val.s, APERM);
			}
			tp->flag &= ~ISSET;
		}
	}
 Search:
	if ((!tp || (tp->type == CTALIAS && !(tp->flag&ISSET))) &&
	    (flags & FC_PATH)) {
		if (!tp) {
			if (insert && !(flags & FC_DEFPATH)) {
				tp = ktenter(&taliases, name, h);
				tp->type = CTALIAS;
			} else {
				tp = &temp;
				tp->type = CEXEC;
			}
			tp->flag = DEFINED;
		}
		npath.ro = search_path(name,
		    (flags & FC_DEFPATH) ? def_path : path,
		    X_OK, &tp->u2.errnov);
		if (npath.ro) {
			strdupx(tp->val.s, npath.ro, APERM);
			if (npath.ro != name)
				afree(npath.rw, ATEMP);
			tp->flag |= ISSET|ALLOC;
		} else if ((flags & FC_FUNC) &&
		    (fpath = str_val(global("FPATH"))) != null &&
		    (npath.ro = search_path(name, fpath, R_OK,
		    &tp->u2.errnov)) != NULL) {
			tp = &temp;
			tp->type = CFUNC;
			tp->flag = DEFINED;
			tp->u.fpath = npath.ro;
		}
	}
	return (tp);
}
struct tbl * findcom ( const char * name , int flags ) { static struct tbl temp ; uint32_t h = hash ( name ) ; struct tbl * tp = NULL , * tbi ; unsigned char insert = Flag ( FTRACKALL ) ; char * fpath ; union mksh_cchack npath ; if ( vstrchr ( name , ' ' ) ) { insert = 0 ; flags &= ~ FC_FUNC ; goto Search ; } tbi = ( flags & FC_BI ) ? ktsearch ( & builtins , name , h ) : NULL ; if ( ( flags & FC_SPECBI ) && tbi && ( tbi -> flag & SPEC_BI ) ) tp = tbi ; if ( ! tp && ( flags & FC_FUNC ) ) { tp = findfunc ( name , h , false ) ; if ( tp && ! ( tp -> flag & ISSET ) ) { if ( ( fpath = str_val ( global ( " " ) ) ) == null ) { tp -> u . fpath = NULL ; tp -> u2 . errnov = ENOENT ; } else tp -> u . fpath = search_path ( name , fpath , R_OK , & tp -> u2 . errnov ) ; } } if ( ! tp && ( flags & FC_NORMBI ) && tbi ) tp = tbi ; if ( ! tp && ( flags & FC_PATH ) && ! ( flags & FC_DEFPATH ) ) { tp = ktsearch ( & taliases , name , h ) ; if ( tp && ( tp -> flag & ISSET ) && ksh_access ( tp -> val . s , X_OK ) != 0 ) { if ( tp -> flag & ALLOC ) { tp -> flag &= ~ ALLOC ; afree ( tp -> val . s , APERM ) ; } tp -> flag &= ~ ISSET ; } } Search : if ( ( ! tp || ( tp -> type == CTALIAS && ! ( tp -> flag & ISSET ) ) ) && ( flags & FC_PATH ) ) { if ( ! tp ) { if ( insert && ! ( flags & FC_DEFPATH ) ) { tp = ktenter ( & taliases , name , h ) ; tp -> type = CTALIAS ; } else { tp = & temp ; tp -> type = CEXEC ; } tp -> flag = DEFINED ; } npath . ro = search_path ( name , ( flags & FC_DEFPATH ) ? def_path : path , X_OK , & tp -> u2 . errnov ) ; if ( npath . ro ) { strdupx ( tp -> val . s , npath . ro , APERM ) ; if ( npath . ro != name ) afree ( npath . rw , ATEMP ) ; tp -> flag |= ISSET | ALLOC ; } else if ( ( flags & FC_FUNC ) && ( fpath = str_val ( global ( " " ) ) ) != null && ( npath . ro = search_path ( name , fpath , R_OK , & tp -> u2 . errnov ) ) != NULL ) { tp = & temp ; tp -> type = CFUNC ; tp -> flag = DEFINED ; tp -> u . fpath = npath . ro ; } } return ( tp ) ; }
find command
 either function, hashed command, or built-in (in that order)
find command either function hashed command or built - in ( in that order )
/* insert if not found */ /* for function autoloading */ /* prevent FPATH search below */ /*
	 * POSIX says special builtins first, then functions, then
	 * regular builtins, then search path...
	 */ /* make ~ISSET */ /*
			 * An undocumented feature of AT&T ksh is that
			 * it searches FPATH if a command is not found,
			 * even if the command hasn't been set up as an
			 * autoloaded function (ie, no typeset -uf).
			 */ /* make ~ISSET */