#include <defs.h>
#include <shell.h>
#include <nval.h>
#include <cmdext.h>
#include <stdio.h>
#include <setjmp.h>
#undef calloc
#undef free
typedef struct {
const char *name;
int (* func)(int, char **, Shbltin_t *);
} bfastpathrec;
#if 0
#define ENABLE_PERFORMANCE_PARADOXON 1
#endif
static const
bfastpathrec fastpath_builtins[] =
{
{ "basename", b_basename },
{ "cat", b_cat },
{ "chgrp", b_chgrp },
{ "chmod", b_chmod },
{ "chown", b_chown },
#ifdef ENABLE_PERFORMANCE_PARADOXON
{ "cksum", b_cksum },
#endif
{ "cmp", b_cmp },
{ "comm", b_comm },
{ "cp", b_cp },
{ "cut", b_cut },
{ "date", b_date },
{ "dirname", b_dirname },
{ "expr", b_expr },
{ "fds", b_fds },
{ "fmt", b_fmt },
{ "fold", b_fold },
{ "getconf", b_getconf },
{ "head", b_head },
{ "id", b_id },
{ "join", b_join },
{ "ln", b_ln },
{ "md5sum", b_md5sum },
{ "mkdir", b_mkdir },
{ "mkfifo", b_mkfifo },
{ "mktemp", b_mktemp },
{ "mv", b_mv },
{ "paste", b_paste },
{ "pathchk", b_pathchk },
{ "pids", b_pids },
#ifdef ENABLE_PERFORMANCE_PARADOXON
{ "rev", b_rev },
#endif
{ "rm", b_rm },
{ "rmdir", b_rmdir },
{ "stty", b_stty },
#ifdef ENABLE_PERFORMANCE_PARADOXON
{ "sum", b_sum },
#endif
{ "sync", b_sync },
{ "tail", b_tail },
{ "tee", b_tee },
{ "tty", b_tty },
{ "uname", b_uname },
{ "uniq", b_uniq },
{ "vmstate", b_vmstate },
{ "wc", b_wc },
{ NULL, NULL }
};
static inline const bfastpathrec *
find_bfastpathrec(const char *name)
{
unsigned int i;
signed int cmpres;
for (i = 0; fastpath_builtins[i].name != NULL; i++) {
cmpres = strcmp(fastpath_builtins[i].name, name);
if (cmpres == 0)
return (&fastpath_builtins[i]);
else if (cmpres > 0)
return (NULL);
}
return (NULL);
}
static inline int
fastpath_builtin_main(const bfastpathrec *brec, int argc, char *argv[])
{
setlocale(LC_ALL, "");
return ((*brec->func)(argc, argv, NULL));
}
static const char *script = "\n"
"typeset cmd=\"${0##*/}\"\n"
"if [[ \"${cmd}\" != ~(Elr)(alias|unalias|command) ]] && "
"! alias \"${cmd}\" >/dev/null 2>&1 ; then\n"
"PATH='' builtin \"${cmd}\"\n"
"fi\n"
"if [[ \"${cmd}\" == \"command\" ]] ; then\n"
"command \"$@\"\n"
"else\n"
"\"${cmd}\" \"$@\"\n"
"fi\n"
"exitval=$?";
static int
script_builtin_main(int argc, char **argv)
{
int i;
Shell_t *shp;
Namval_t *np;
int exitval;
char **xargv;
xargv = calloc(argc + 2, sizeof (char *));
if (xargv == NULL)
return (1);
xargv[0] = "/usr/bin/sh";
for (i = 0; i < argc; i++)
xargv[i + 1] = argv[i];
xargv[i + 1] = NULL;
shp = sh_init(argc + 1, xargv, 0);
if (!shp)
error(ERROR_exit(1), "shell initialisation failed.");
if (setjmp(*shp->jmplist) == 0)
(void) sh_trap(script, 0);
np = nv_open("exitval", shp->var_tree, 0);
if (!np)
error(ERROR_exit(1), "variable %s not found.", "exitval");
exitval = (int)nv_getnum(np);
nv_close(np);
free(xargv);
return (exitval);
}
int
main(int argc, char **argv)
{
const char *progname;
const bfastpathrec *brec;
char execnamebuff[PATH_MAX + 1];
if (pathprog(argv[0], execnamebuff, sizeof (execnamebuff)) <= 0)
error(ERROR_exit(1), "could not determinate exec name.");
progname = (const char *)strrchr(execnamebuff, '/');
if (progname != NULL)
progname++;
else
progname = execnamebuff;
if (brec = find_bfastpathrec(progname)) {
return (fastpath_builtin_main(brec, argc, argv));
} else {
return (script_builtin_main(argc, argv));
}
}