invent builtin flags instead of special-casing cat and printf for prefer-external-over-builtin stuff
This commit is contained in:
parent
5401a55a98
commit
e8bbf79d8c
83
exec.c
83
exec.c
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.176 2016/07/24 23:07:19 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.177 2016/07/24 23:10:02 tg Exp $");
|
||||||
|
|
||||||
#ifndef MKSH_DEFAULT_EXECSHELL
|
#ifndef MKSH_DEFAULT_EXECSHELL
|
||||||
#define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh"
|
#define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh"
|
||||||
|
@ -533,11 +533,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
||||||
}
|
}
|
||||||
if ((tp = findcom(cp, FC_BI)) == NULL)
|
if ((tp = findcom(cp, FC_BI)) == NULL)
|
||||||
errorf("%s: %s: %s", Tbuiltin, cp, "not a builtin");
|
errorf("%s: %s: %s", Tbuiltin, cp, "not a builtin");
|
||||||
if (tp->type == CSHELL && (tp->val.f == c_cat
|
if (tp->type == CSHELL && (tp->flag & LOW_BI))
|
||||||
#ifdef MKSH_PRINTF_BUILTIN
|
|
||||||
|| tp->val.f == c_printf
|
|
||||||
#endif
|
|
||||||
))
|
|
||||||
break;
|
break;
|
||||||
continue;
|
continue;
|
||||||
} else if (tp->val.f == c_exec) {
|
} else if (tp->val.f == c_exec) {
|
||||||
|
@ -595,29 +591,21 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
||||||
subst_exstat = 0;
|
subst_exstat = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (tp->val.f == c_cat) {
|
} else if (tp->flag & LOW_BI) {
|
||||||
/* if we have any flags, do not use the builtin */
|
/* if we have any flags, do not use the builtin */
|
||||||
if (ap[1] && ap[1][0] == '-' && ap[1][1] != '\0' &&
|
if ((ap[1] && ap[1][0] == '-' && ap[1][1] != '\0' &&
|
||||||
/* argument, begins with -, is not - or -- */
|
/* argument, begins with -, is not - or -- */
|
||||||
(ap[1][1] != '-' || ap[1][2] != '\0')) {
|
(ap[1][1] != '-' || ap[1][2] != '\0')) ||
|
||||||
struct tbl *ext_cat;
|
/* always prefer the external utility */
|
||||||
|
(tp->flag & LOWER_BI)) {
|
||||||
|
struct tbl *ext_cmd;
|
||||||
|
|
||||||
ext_cat = findcom(Tcat, FC_PATH | FC_FUNC);
|
ext_cmd = findcom(tp->name, FC_PATH | FC_FUNC);
|
||||||
if (ext_cat && (ext_cat->type != CTALIAS ||
|
if (ext_cmd && (ext_cmd->type != CTALIAS ||
|
||||||
(ext_cat->flag & ISSET)))
|
(ext_cmd->flag & ISSET)))
|
||||||
tp = ext_cat;
|
tp = ext_cmd;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef MKSH_PRINTF_BUILTIN
|
|
||||||
} else if (tp->val.f == c_printf) {
|
|
||||||
struct tbl *ext_printf;
|
|
||||||
|
|
||||||
ext_printf = findcom(Tprintf, FC_PATH | FC_FUNC);
|
|
||||||
if (ext_printf && (ext_printf->type != CTALIAS ||
|
|
||||||
(ext_printf->flag & ISSET)))
|
|
||||||
tp = ext_printf;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
} else if (tp->val.f == c_trap) {
|
} else if (tp->val.f == c_trap) {
|
||||||
t->u.evalflags &= ~DOTCOMEXEC;
|
t->u.evalflags &= ~DOTCOMEXEC;
|
||||||
break;
|
break;
|
||||||
|
@ -727,16 +715,12 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
|
||||||
!(ftp = findfunc(cp, hash(cp), false)) ||
|
!(ftp = findfunc(cp, hash(cp), false)) ||
|
||||||
!(ftp->flag & ISSET)) {
|
!(ftp->flag & ISSET)) {
|
||||||
rv = errno;
|
rv = errno;
|
||||||
if (!strcmp(cp, Tcat)) {
|
if ((ftp = findcom(cp, FC_BI)) &&
|
||||||
tp = findcom(Tcat, FC_BI);
|
(ftp->type == CSHELL) &&
|
||||||
|
(ftp->flag & LOW_BI)) {
|
||||||
|
tp = ftp;
|
||||||
goto do_call_builtin;
|
goto do_call_builtin;
|
||||||
}
|
}
|
||||||
#ifdef MKSH_PRINTF_BUILTIN
|
|
||||||
if (!strcmp(cp, Tprintf)) {
|
|
||||||
tp = findcom(Tprintf, FC_BI);
|
|
||||||
goto do_call_builtin;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (rv) {
|
if (rv) {
|
||||||
tp->u2.errnov = rv;
|
tp->u2.errnov = rv;
|
||||||
cp = tp->u.fpath;
|
cp = tp->u.fpath;
|
||||||
|
@ -1089,23 +1073,38 @@ builtin(const char *name, int (*func) (const char **))
|
||||||
uint32_t flag = DEFINED;
|
uint32_t flag = DEFINED;
|
||||||
|
|
||||||
/* see if any flags should be set for this builtin */
|
/* see if any flags should be set for this builtin */
|
||||||
while (1) {
|
flags_loop:
|
||||||
if (*name == '=')
|
switch (*name) {
|
||||||
/* command does variable assignment */
|
case '=':
|
||||||
flag |= KEEPASN;
|
/* command does variable assignment */
|
||||||
else if (*name == '*')
|
flag |= KEEPASN;
|
||||||
/* POSIX special builtin */
|
break;
|
||||||
flag |= SPEC_BI;
|
case '*':
|
||||||
else
|
/* POSIX special builtin */
|
||||||
break;
|
flag |= SPEC_BI;
|
||||||
name++;
|
break;
|
||||||
|
case '~':
|
||||||
|
/* external utility overrides built-in utility, always */
|
||||||
|
flag |= LOWER_BI;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case '!':
|
||||||
|
/* external utility overrides built-in utility, with flags */
|
||||||
|
flag |= LOW_BI;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto flags_seen;
|
||||||
}
|
}
|
||||||
|
++name;
|
||||||
|
goto flags_loop;
|
||||||
|
flags_seen:
|
||||||
|
|
||||||
|
/* enter into the builtins hash table */
|
||||||
tp = ktenter(&builtins, name, hash(name));
|
tp = ktenter(&builtins, name, hash(name));
|
||||||
tp->flag = flag;
|
tp->flag = flag;
|
||||||
tp->type = CSHELL;
|
tp->type = CSHELL;
|
||||||
tp->val.f = func;
|
tp->val.f = func;
|
||||||
|
|
||||||
|
/* return name, for direct builtin call check in main.c */
|
||||||
return (name);
|
return (name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
6
funcs.c
6
funcs.c
|
@ -38,7 +38,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.297 2016/06/26 00:44:25 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.298 2016/07/24 23:10:02 tg Exp $");
|
||||||
|
|
||||||
#if HAVE_KILLPG
|
#if HAVE_KILLPG
|
||||||
/*
|
/*
|
||||||
|
@ -101,7 +101,7 @@ const struct builtin mkshbuiltins[] = {
|
||||||
{Talias, c_alias},
|
{Talias, c_alias},
|
||||||
{"*=break", c_brkcont},
|
{"*=break", c_brkcont},
|
||||||
{Tgbuiltin, c_builtin},
|
{Tgbuiltin, c_builtin},
|
||||||
{Tcat, c_cat},
|
{"!cat", c_cat},
|
||||||
{"cd", c_cd},
|
{"cd", c_cd},
|
||||||
/* dash compatibility hack */
|
/* dash compatibility hack */
|
||||||
{"chdir", c_cd},
|
{"chdir", c_cd},
|
||||||
|
@ -155,7 +155,7 @@ const struct builtin mkshbuiltins[] = {
|
||||||
{"mknod", c_mknod},
|
{"mknod", c_mknod},
|
||||||
#endif
|
#endif
|
||||||
#ifdef MKSH_PRINTF_BUILTIN
|
#ifdef MKSH_PRINTF_BUILTIN
|
||||||
{Tprintf, c_printf},
|
{"~printf", c_printf},
|
||||||
#endif
|
#endif
|
||||||
#if HAVE_SELECT
|
#if HAVE_SELECT
|
||||||
{"sleep", c_sleep},
|
{"sleep", c_sleep},
|
||||||
|
|
2
main.c
2
main.c
|
@ -34,7 +34,7 @@
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.310 2016/02/26 21:53:36 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.311 2016/07/24 23:10:03 tg Exp $");
|
||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
|
|
9
sh.h
9
sh.h
|
@ -175,7 +175,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTERN
|
#ifdef EXTERN
|
||||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.775 2016/07/12 23:07:10 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.776 2016/07/24 23:10:04 tg Exp $");
|
||||||
#endif
|
#endif
|
||||||
#define MKSH_VERSION "R52 2016/07/12"
|
#define MKSH_VERSION "R52 2016/07/12"
|
||||||
|
|
||||||
|
@ -864,13 +864,9 @@ EXTERN const char T_typeset[] E_INIT("=typeset");
|
||||||
#define Ttypeset (T_typeset + 1) /* "typeset" */
|
#define Ttypeset (T_typeset + 1) /* "typeset" */
|
||||||
EXTERN const char Talias[] E_INIT("alias");
|
EXTERN const char Talias[] E_INIT("alias");
|
||||||
EXTERN const char Tunalias[] E_INIT("unalias");
|
EXTERN const char Tunalias[] E_INIT("unalias");
|
||||||
EXTERN const char Tcat[] E_INIT("cat");
|
|
||||||
#ifdef __OS2__
|
#ifdef __OS2__
|
||||||
EXTERN const char Textproc[] E_INIT("extproc");
|
EXTERN const char Textproc[] E_INIT("extproc");
|
||||||
#endif
|
#endif
|
||||||
#ifdef MKSH_PRINTF_BUILTIN
|
|
||||||
EXTERN const char Tprintf[] E_INIT("printf");
|
|
||||||
#endif
|
|
||||||
EXTERN const char Tsgset[] E_INIT("*=set");
|
EXTERN const char Tsgset[] E_INIT("*=set");
|
||||||
#define Tset (Tsgset + 2) /* "set" */
|
#define Tset (Tsgset + 2) /* "set" */
|
||||||
EXTERN const char Tsgexport[] E_INIT("*=export");
|
EXTERN const char Tsgexport[] E_INIT("*=export");
|
||||||
|
@ -1243,6 +1239,9 @@ EXTERN bool last_lookup_was_array;
|
||||||
#define FDELETE BIT(10) /* function deleted while it was executing */
|
#define FDELETE BIT(10) /* function deleted while it was executing */
|
||||||
#define FKSH BIT(11) /* function defined with function x (vs x()) */
|
#define FKSH BIT(11) /* function defined with function x (vs x()) */
|
||||||
#define SPEC_BI BIT(12) /* a POSIX special builtin */
|
#define SPEC_BI BIT(12) /* a POSIX special builtin */
|
||||||
|
#define LOWER_BI BIT(13) /* (with LOW_BI) override even w/o flags */
|
||||||
|
#define LOW_BI BIT(14) /* external utility overrides built-in one */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attributes that can be set by the user (used to decide if an unset
|
* Attributes that can be set by the user (used to decide if an unset
|
||||||
* param should be repoted by set/typeset). Does not include ARRAY or
|
* param should be repoted by set/typeset). Does not include ARRAY or
|
||||||
|
|
Loading…
Reference in New Issue