81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik/*
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * CDDL HEADER START
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik *
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * The contents of this file are subject to the terms of the
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * Common Development and Distribution License (the "License").
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * You may not use this file except in compliance with the License.
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik *
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * or http://www.opensolaris.org/os/licensing.
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * See the License for the specific language governing permissions
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * and limitations under the License.
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik *
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * When distributing Covered Code, include this CDDL HEADER in each
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * If applicable, add the following below this CDDL HEADER, with the
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * fields enclosed by brackets "[]" replaced with your own identifying
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * information: Portions Copyright [yyyy] [name of copyright owner]
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik *
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * CDDL HEADER END
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik */
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik/*
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * Use is subject to license terms.
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik */
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik/*
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * alias.c is a C version of the alias.sh wrapper (which links ksh
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * builtins to commands in /usr/bin/, e.g. calling this wrapper as
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * /usr/bin/alias will call the ksh "alias" builtin, running it as
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * /usr/bin/cut will call the ksh "cut" builtin etc.
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik */
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik#include <shell.h>
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik#include <nval.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include <cmdext.h>
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik#include <stdio.h>
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainztypedef struct {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz const char *name;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int (* func)(int, char **, void *);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz} bfastpathrec;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz/*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * We've disabled the "fastpath" codepath for some commands below
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * because it causes a paradoxon for large input files (as used by
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * ON PerfPIT for testing). For /usr/bin/rev (where the issue was
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * first discovered) it looks like this:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * - for small files like /etc/profile the fastpath is faster in a loop
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * with 1000 iterations (8 seconds with fastpath, 14 seconds without
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * fastpath)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * - for large files (/usr/pub/UTF-8 replicated until the test file
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * reaches 24884706 bytes) the benchmark reverses: The fastpath now
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * needs 40 seconds and without fastpath it needs 30 seconds (for 100
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * iterations).
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#if 0
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#define ENABLE_PERFORMANCE_PARADOXON 1
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz/*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * List of libcmd builtins which do not require a |Shell_t| context.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * This list was automatically generated from <ast/cmdext.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic const
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzbfastpathrec fastpath_builtins[] =
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /* This list must be alphabetically sorted for |strcmp()| usage */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "basename", b_basename },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "cat", b_cat },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "chgrp", b_chgrp },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "chmod", b_chmod },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "chown", b_chown },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#ifdef ENABLE_PERFORMANCE_PARADOXON
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "cksum", b_cksum },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif /* ENABLE_PERFORMANCE_PARADOXON */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "cmp", b_cmp },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "comm", b_comm },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "cp", b_cp },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "cut", b_cut },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "date", b_date },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "dirname", b_dirname },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "egrep", b_egrep },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "expr", b_expr },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "fds", b_fds },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "fgrep", b_fgrep },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "fmt", b_fmt },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "fold", b_fold },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "getconf", b_getconf },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "grep", b_grep },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "head", b_head },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "id", b_id },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "join", b_join },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "ln", b_ln },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "logname", b_logname },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "md5sum", b_md5sum },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "mkdir", b_mkdir },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "mkfifo", b_mkfifo },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "mktemp", b_mktemp },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "mv", b_mv },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "paste", b_paste },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "pathchk", b_pathchk },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "pids", b_pids },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "readlink", b_readlink },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#ifdef ENABLE_PERFORMANCE_PARADOXON
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "rev", b_rev },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif /* ENABLE_PERFORMANCE_PARADOXON */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "rm", b_rm },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "rmdir", b_rmdir },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "stty", b_stty },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#ifdef ENABLE_PERFORMANCE_PARADOXON
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "sum", b_sum },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif /* ENABLE_PERFORMANCE_PARADOXON */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "sync", b_sync },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "tail", b_tail },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "tee", b_tee },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "tty", b_tty },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "uname", b_uname },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "uniq", b_uniq },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "wc", b_wc },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { "xgrep", b_xgrep },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { NULL, (int (*)(int, char **, void *))NULL }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz};
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic inline
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzconst bfastpathrec *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzfind_bfastpathrec(const char *name)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz unsigned int i;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz signed int cmpres;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for (i = 0; fastpath_builtins[i].name != NULL; i++) {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz cmpres = strcmp(fastpath_builtins[i].name, name);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (cmpres == 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return (&fastpath_builtins[i]);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (cmpres > 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return (NULL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return (NULL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic inline
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzint
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzfastpath_builtin_main(const bfastpathrec *brec, int argc, char *argv[])
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz setlocale(LC_ALL, ""); /* calls |_ast_setlocale()| */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return ((*brec->func)(argc, argv, NULL));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik/* Builtin script, original derived from alias.sh */
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dikstatic const char *script = "\n"
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik/* Get name of builtin */
9a6f360e750e0b14fc9b9bf8347e0ebad3959e3fCasper H.S. Dik"typeset cmd=\"${0##*/}\"\n"
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik/*
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * If the requested command is not an alias load it explicitly
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * to make sure it is not bound to a path (those built-ins which
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * are mapped via shell aliases point to commands which are
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * "special shell built-ins" which cannot be bound to a specific
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * PATH element) - otherwise we may execute the wrong command
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * if an executable with the same name sits in a PATH element
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * before /usr/bin (e.g. /usr/xpg4/bin/ls would be executed
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * before /usr/bin/ls if the path was something like
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * PATH=/usr/xpg4/bin:/usr/bin).
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik */
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik"if [[ \"${cmd}\" != ~(Elr)(alias|unalias|command) ]] && "
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik "! alias \"${cmd}\" >/dev/null 2>&1 ; then\n"
d185aafa0dcc4aa576fc668a1d1ce3a28660c456Olga Kryzhanovska "PATH='' builtin \"${cmd}\"\n"
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik"fi\n"
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik/* command is a keyword and needs to be handled separately */
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik"if [[ \"${cmd}\" == \"command\" ]] ; then\n"
9a6f360e750e0b14fc9b9bf8347e0ebad3959e3fCasper H.S. Dik "command \"$@\"\n"
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik"else\n"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#ifdef WORKAROUND_FOR_ALIAS_CRASH
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz/*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * Work around a crash in /usr/bin/alias when invalid options are
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * passed (e.g. $ /usr/bin/alias -c #). The shell code will call
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * an error handler which does a |longjmp()| but somehow the code
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * failed to do the |setjmp()| before this point.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * Putting the "alias" command in a subshell avoids the crash.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * Real cause of the issue is under investigation and a fix be
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * delivered with the next ast-ksh update.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz "( \"${cmd}\" \"$@\" )\n"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#else
9a6f360e750e0b14fc9b9bf8347e0ebad3959e3fCasper H.S. Dik "\"${cmd}\" \"$@\"\n"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif /* WORKAROUND_FOR_ALIAS_CRASH */
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik"fi\n"
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik"exitval=$?";
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic inline
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dikint
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzscript_builtin_main(int argc, char *argv[])
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik{
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik int i;
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik Shell_t *shp;
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik Namval_t *np;
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik int exitval;
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik /*
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * Create copy of |argv| array shifted by one position to
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * emulate $ /usr/bin/sh <scriptname> <args1> <arg2> ... #.
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * First position is set to "/usr/bin/sh" since other
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * values may trigger special shell modes (e.g. *rsh* will
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik * trigger "restricted" shell mode etc.).
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik */
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik char *xargv[argc+2];
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik xargv[0] = "/usr/bin/sh";
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik xargv[1] = "scriptname";
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik for (i = 0; i < argc; i++) {
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik xargv[i+1] = argv[i];
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik }
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik xargv[i+1] = NULL;
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik shp = sh_init(argc+1, xargv, 0);
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik if (!shp)
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik error(ERROR_exit(1), "shell initialisation failed.");
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik (void) sh_trap(script, 0);
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik np = nv_open("exitval", shp->var_tree, 0);
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik if (!np)
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik error(ERROR_exit(1), "variable %s not found.", "exitval");
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik exitval = (int)nv_getnum(np);
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik nv_close(np);
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik return (exitval);
81af778e872fc2ec5f0ac36e7b25bdb24ebd2d6aCasper H.S. Dik}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzint
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzmain(int argc, char *argv[])
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz const char *progname;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz const bfastpathrec *brec;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char execnamebuff[PATH_MAX+1];
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /* Get program name */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (pathprog(argv[0], execnamebuff, sizeof (execnamebuff)) <= 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(ERROR_exit(1), "could not determinate exec name.");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz progname = (const char *)strrchr(execnamebuff, '/');
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (progname != NULL) {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz progname++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz progname = execnamebuff;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /* Execute command... */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (brec = find_bfastpathrec(progname)) {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /* ... either via a fast path (calling the code directly) ... */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return (fastpath_builtin_main(brec, argc, argv));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /* ... or from within a full shell. */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return (script_builtin_main(argc, argv));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}