summaryrefslogtreecommitdiff
path: root/usr/src/cmd/ksh
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/ksh')
-rw-r--r--usr/src/cmd/ksh/Makefile.testshell5
-rw-r--r--usr/src/cmd/ksh/builtins/Makefile30
-rw-r--r--usr/src/cmd/ksh/builtins/alias.c163
3 files changed, 190 insertions, 8 deletions
diff --git a/usr/src/cmd/ksh/Makefile.testshell b/usr/src/cmd/ksh/Makefile.testshell
index fdad066a57..ef520d4d04 100644
--- a/usr/src/cmd/ksh/Makefile.testshell
+++ b/usr/src/cmd/ksh/Makefile.testshell
@@ -20,7 +20,7 @@
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -101,7 +101,7 @@ testshell: $(PROG)
printf "# which ksh='%s', ksh93='%s'\n" \
"$$(which ksh)" "$$(which ksh93)" ; \
) ; \
- if [[ "$$(isalist)" != ~(E)$(LIBSHELLMACH) ]] ; then \
+ if [[ "$$(isalist)" != ~(F)$(LIBSHELLMACH) ]] ; then \
printf \
"# ISA='%s' not available on this system, skipping tests...\n" \
"$(LIBSHELLMACH)" ; \
@@ -135,6 +135,7 @@ testshell: $(PROG)
"$$(basename "$${test_item}")" \
"$${mode%:*}"; \
( \
+ ulimit -s 65536 ; \
test_output="$$( ( \
export \
SHELL="$(SRC)/cmd/ksh/$(LIBSHELLMACH)/ksh" \
diff --git a/usr/src/cmd/ksh/builtins/Makefile b/usr/src/cmd/ksh/builtins/Makefile
index fcc92f323e..52808250c7 100644
--- a/usr/src/cmd/ksh/builtins/Makefile
+++ b/usr/src/cmd/ksh/builtins/Makefile
@@ -30,29 +30,43 @@ PROG= alias
ALIASPROG= \
bg \
cd \
+ cksum \
+ cmp \
+ comm \
command \
+ cut \
fc \
fg \
getopts \
hash \
jobs \
+ join \
kill \
+ logname \
+ paste \
+ print \
read \
rev \
sleep \
sum \
+ tee \
test \
type \
ulimit \
umask \
unalias \
- wait
+ uniq \
+ wait \
+ wc
include ../../Makefile.cmd
+$(SPARC_BLD)include ../../Makefile.cmd.64
ROOTALIASPROG= $(ALIASPROG:%=$(ROOTBIN)/%)
FILEMODE= 555
+OWNER= root
+GROUP= bin
.KEEP_STATE:
@@ -61,8 +75,6 @@ all: $(PROG)
$(ROOTBIN)/%: $(ROOTBIN)/alias
$(INS.link)
-include ../../Makefile.cmd
-
.KEEP_STATE:
# Set common AST build flags (e.g., needed to support the math stuff).
@@ -73,11 +85,19 @@ OBJECTS= \
SRCS= $(OBJECTS:%.o=%.c)
-LDLIBS += -lshell -last
+GROUP= bin
+LDLIBS += -lshell -lcmd -last
CPPFLAGS = \
$(DTEXTDOM) $(DTS_ERRNO) \
- -I$(ROOT)/usr/include/ast
+ -I$(ROOT)/usr/include/ast \
+ -I$(ROOT)/usr/include
+
+# Enable workaround for a crash in /usr/bin/alias when invalid
+# options are passed (e.g. $ /usr/bin/alias -c #). The shell
+# code will call an error handler which does a |longjmp()| but
+# somehow the code failed to do the |setjmp()| before this point.
+CPPFLAGS += -DWORKAROUND_FOR_ALIAS_CRASH
CFLAGS += \
$(ASTCFLAGS)
diff --git a/usr/src/cmd/ksh/builtins/alias.c b/usr/src/cmd/ksh/builtins/alias.c
index b477d7353c..dd789ef844 100644
--- a/usr/src/cmd/ksh/builtins/alias.c
+++ b/usr/src/cmd/ksh/builtins/alias.c
@@ -33,8 +33,122 @@
#include <shell.h>
#include <nval.h>
+#include <cmdext.h>
#include <stdio.h>
+typedef struct {
+ const char *name;
+ int (* func)(int, char **, void *);
+} bfastpathrec;
+
+/*
+ * We've disabled the "fastpath" codepath for some commands below
+ * because it causes a paradoxon for large input files (as used by
+ * ON PerfPIT for testing). For /usr/bin/rev (where the issue was
+ * first discovered) it looks like this:
+ * - for small files like /etc/profile the fastpath is faster in a loop
+ * with 1000 iterations (8 seconds with fastpath, 14 seconds without
+ * fastpath)
+ * - for large files (/usr/pub/UTF-8 replicated until the test file
+ * reaches 24884706 bytes) the benchmark reverses: The fastpath now
+ * needs 40 seconds and without fastpath it needs 30 seconds (for 100
+ * iterations).
+ */
+#if 0
+#define ENABLE_PERFORMANCE_PARADOXON 1
+#endif
+
+/*
+ * List of libcmd builtins which do not require a |Shell_t| context.
+ * This list was automatically generated from <ast/cmdext.h>
+ */
+static const
+bfastpathrec fastpath_builtins[] =
+{
+ /* This list must be alphabetically sorted for |strcmp()| usage */
+ { "basename", b_basename },
+ { "cat", b_cat },
+ { "chgrp", b_chgrp },
+ { "chmod", b_chmod },
+ { "chown", b_chown },
+#ifdef ENABLE_PERFORMANCE_PARADOXON
+ { "cksum", b_cksum },
+#endif /* ENABLE_PERFORMANCE_PARADOXON */
+ { "cmp", b_cmp },
+ { "comm", b_comm },
+ { "cp", b_cp },
+ { "cut", b_cut },
+ { "date", b_date },
+ { "dirname", b_dirname },
+ { "egrep", b_egrep },
+ { "expr", b_expr },
+ { "fds", b_fds },
+ { "fgrep", b_fgrep },
+ { "fmt", b_fmt },
+ { "fold", b_fold },
+ { "getconf", b_getconf },
+ { "grep", b_grep },
+ { "head", b_head },
+ { "id", b_id },
+ { "join", b_join },
+ { "ln", b_ln },
+ { "logname", b_logname },
+ { "md5sum", b_md5sum },
+ { "mkdir", b_mkdir },
+ { "mkfifo", b_mkfifo },
+ { "mktemp", b_mktemp },
+ { "mv", b_mv },
+ { "paste", b_paste },
+ { "pathchk", b_pathchk },
+ { "pids", b_pids },
+ { "readlink", b_readlink },
+#ifdef ENABLE_PERFORMANCE_PARADOXON
+ { "rev", b_rev },
+#endif /* ENABLE_PERFORMANCE_PARADOXON */
+ { "rm", b_rm },
+ { "rmdir", b_rmdir },
+ { "stty", b_stty },
+#ifdef ENABLE_PERFORMANCE_PARADOXON
+ { "sum", b_sum },
+#endif /* ENABLE_PERFORMANCE_PARADOXON */
+ { "sync", b_sync },
+ { "tail", b_tail },
+ { "tee", b_tee },
+ { "tty", b_tty },
+ { "uname", b_uname },
+ { "uniq", b_uniq },
+ { "wc", b_wc },
+ { "xgrep", b_xgrep },
+ { NULL, (int (*)(int, char **, void *))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, ""); /* calls |_ast_setlocale()| */
+
+ return ((*brec->func)(argc, argv, NULL));
+}
+
+
/* Builtin script, original derived from alias.sh */
static const char *script = "\n"
/* Get name of builtin */
@@ -58,12 +172,27 @@ static const char *script = "\n"
"if [[ \"${cmd}\" == \"command\" ]] ; then\n"
"command \"$@\"\n"
"else\n"
+#ifdef WORKAROUND_FOR_ALIAS_CRASH
+/*
+ * Work around a crash in /usr/bin/alias when invalid options are
+ * passed (e.g. $ /usr/bin/alias -c #). The shell code will call
+ * an error handler which does a |longjmp()| but somehow the code
+ * failed to do the |setjmp()| before this point.
+ * Putting the "alias" command in a subshell avoids the crash.
+ * Real cause of the issue is under investigation and a fix be
+ * delivered with the next ast-ksh update.
+ */
+ "( \"${cmd}\" \"$@\" )\n"
+#else
"\"${cmd}\" \"$@\"\n"
+#endif /* WORKAROUND_FOR_ALIAS_CRASH */
"fi\n"
"exitval=$?";
+
+static inline
int
-main(int argc, char *argv[])
+script_builtin_main(int argc, char *argv[])
{
int i;
Shell_t *shp;
@@ -98,3 +227,35 @@ main(int argc, char *argv[])
return (exitval);
}
+
+int
+main(int argc, char *argv[])
+{
+ const char *progname;
+ const bfastpathrec *brec;
+ char execnamebuff[PATH_MAX+1];
+
+ /* Get program name */
+ 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;
+ }
+
+ /* Execute command... */
+ if (brec = find_bfastpathrec(progname)) {
+ /* ... either via a fast path (calling the code directly) ... */
+ return (fastpath_builtin_main(brec, argc, argv));
+ }
+ else
+ {
+ /* ... or from within a full shell. */
+ return (script_builtin_main(argc, argv));
+ }
+}