# # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2021 OmniOS Community Edition (OmniOSce) Association. # SHELL= /bin/ksh93 PROG= ksh USRKSH_ALIAS_LIST=ksh ksh93 rksh rksh93 include ../../Makefile.cmd # Hammerhead: amd64-only SUBDIRS= $(MACH64) SUBDIRS += builtins ARCH32_i386= i86 ARCH32_sparc= sparcv7 ARCH32= $(ARCH32_$(MACH)) all : TARGET = all install : TARGET = install clean : TARGET = clean clobber : TARGET = clobber lint : TARGET = lint testshell : TARGET = testshell .KEEP_STATE: # Serialise the build to avoid running the test suite for 32-bit # and 64-bit in parallel .NOTPARALLEL: $(SUBDIRS) all clean clobber lint testshell: $(SUBDIRS) install_h _feature: # dummy file since AST/ksh doesn't use *.po files # (and "ksh" is just a frontend which calls directly into libshell, # i.e. there are no l10n strings here) $(PROG).po: $(RM) ksh.po ksh93.po ; \ $(TOUCH) $(PROG).po install: $(SUBDIRS) @(set -o xtrace ; \ builtin ln ; \ builtin rm ; \ for i in $(USRKSH_ALIAS_LIST) ; do \ [[ "$$i" == "$(PROG)" ]] && continue ; \ rm -f "$(ROOTESSBIN)/$$i" ; \ ln "$(ROOTESSBIN)/$(PROG)" "$(ROOTESSBIN)/$$i" ; \ done \ ) $(RM) $(ROOTESSBIN)/jsh $(SYMLINK) ksh93 $(ROOTESSBIN)/jsh $(RM) $(ROOTLIB)/rsh $(SYMLINK) /bin/ksh93 $(ROOTLIB)/rsh $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) FRC: include ../../Makefile.targ # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. # # Copyright (c) 2018, Joyent, Inc. # Copyright 2021 OmniOS Community Edition (OmniOSce) Association. # Hammerhead: use /bin/sh instead of ksh93 to reduce memory per parallel job SHELL=/bin/sh PROG= ksh USRKSH_ALIAS_LIST=ksh ksh93 rksh rksh93 # Set common AST build flags (e.g., needed to support the math stuff). include ../../Makefile.ast OBJECTS= pmain.o ASTSRC= $(C_AST)/src/cmd/ksh93 LIBSHELLBASE= ../../libshell LIBSHELLSRC= $(ASTSRC)/sh SRCS= $(OBJECTS:%.o=$(LIBSHELLSRC)/%.c) LDLIBS += -lshell -lumem # We use "=" here since using $(CPPFLAGS.master) is very tricky in our # case - it MUST come as the last element but future changes in -D options # may then cause silent breakage in the AST sources because the last -D # option specified overrides previous -D options so we prefer the current # way to explicitly list each single flag. CPPFLAGS= \ $(DTEXTDOM) $(DTS_ERRNO) \ $(LIBSHELLCPPFLAGS) CFLAGS += $(ASTCFLAGS) CFLAGS64 += $(ASTCFLAGS64) # Workaround for CR#6628728 ("|memcntl()| prototype not available for C99/XPG6") pmain.o : CERRWARN += -Wno-implicit-function-declaration # not linted SMATCH=off .KEEP_STATE: %.o: $(LIBSHELLSRC)/%.c $(COMPILE.c) -c -o $@ $< $(POST_PROCESS_O) all: $(PROG) # We explicitly delete "ksh" and "ksh93" to catch changes in # BUILD_KSH93_AS_BINKSH (see Makefile.ksh93switch) # and soft-link $(PROG) to ksh/ksh93 below because ksh93 test # suite seems to require that ksh93 is available as "ksh" in # ${PATH} (see comment about "io.sh" in Makefile.testshell). $(PROG): $(OBJECTS) $(RM) ksh ksh93 $(LINK.c) $(OBJECTS) -o $@ $(LDLIBS) $(POST_PROCESS) (set +o errexit ; \ [[ ! -x ksh93 ]] && ln $(PROG) ksh93 ; \ [[ ! -x ksh ]] && ln $(PROG) ksh ; \ true \ ) clean: $(RM) $(OBJECTS) # We explicitly delete "ksh" and "ksh93" to catch changes in # BUILD_KSH93_AS_BINKSH (see Makefile.ksh93switch) CLOBBERFILES += ksh ksh93 # Install rule for $(MACH)/Makefile (32bit) INSTALL.ksh.32bit=@ \ (print "$(POUND_SIGN) Installing 32bit $(PROG) aliases $(USRKSH_ALIAS_LIST)" ; \ set -o xtrace ; \ for i in $(USRKSH_ALIAS_LIST) ; do \ [[ "$$i" == "$(PROG)" ]] && continue ; \ $(RM) "$(ROOTBIN32)/$$i" ; \ $(LN) "$(ROOTBIN32)/$(PROG)" "$(ROOTBIN32)/$$i" ; \ done \ ) # Hammerhead: INSTALL.ksh.64bit removed — ROOTBIN64=ROOTBIN (path flattening), # so ../../bin symlinks from /usr/bin would be circular. # The amd64/Makefile installs directly without alias symlinks. include ../Makefile.testshell # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. # # # Run the ksh93 minimum set of tests # # # Notes: # - "builtins.sh" may fail in some locales like this: # -- snip -- # ## Running ksh test: LANG='zh_TW.EUC' script='builtins.sh' # builtins.sh[274]: printf "%T" now # -- snip -- # # - "options.sh" may currently fail in some locales with: # -- snip -- # options.sh[145]: -G ** failed -- expected 'bam.c bar bar.c bar/bam.c bar/foo.c foo foo/bam.c', got 'bam.c bar bar/bam.c bar.c bar/foo.c foo foo/bam.c' # options.sh[149]: -G **/*.c failed -- expected 'bam.c bar.c bar/bam.c bar/foo.c foo/bam.c', got 'bam.c bar/bam.c bar.c bar/foo.c foo/bam.c' # -- snip -- # This may be simply a different sort order or a bug in the test suite. # Currently under investigation. # # - "glob.sh" may currently fail in some locales (e.g. en_US.UTF-8) with: # -- snip -- # glob.sh[157] glob -- expected '
', got '
' # glob.sh[277] glob -- expected ' ', got ' ' # -- snip -- # This may be simply a different sort order or a bug in the test suite. # Currently under investigation. # # - These tests need a working system clock, otherwise they'll bite you. # # - The current list of locales was mainly composed to cover various encodings # and all important markets based on suggestions by Sun's i18n team. # # - More locales should be tested here (via ON_KSH_TEST_LOCALES below). # Locales like "ru_RU.KOI8-R","de_DE.UTF-8", "is_IS.ISO8859-1", # "is_IS.UTF-8" and "nl_BE.ISO8859-15" are on our wishlist - but # that is getting little bit more compliciated because these locales use # ',' as decimal delimter. The best solution may be to wait for ksh93 # being integrated into OS/Net and then change the test sequence to # use ksh93's associative/compound variables (this may require a flag # day... ;-( ). # # - Due to the timing sensitivity of some of the tests, these tests should # be run on a quiet system with no other activity. # TESTSRC= $(LIBSHELLBASE)/common/tests # ON_KSH_TEST_LOCALES can be overridden via # $ export ON_KSH_TEST_LOCALES= # before $ make install # ON_KSH_TEST_LOCALES = \ C \ en_US.UTF-8 en_US en_US.ISO8859-15@euro \ he_IL.UTF-8 \ hi_IN.UTF-8 \ ja ja_JP.PCK ja_JP.UTF-8 ja_JP.eucJP \ ko_KR.UTF-8 ko_KR.EUC \ th_TH.TIS620 \ zh_CN.EUC zh_CN.GBK \ zh_CN.GB18030 zh_CN.GB18030@pinyin zh_CN.GB18030@radical zh_CN.GB18030@stroke \ zh_CN.UTF-8 zh_CN.UTF-8@pinyin zh_CN.UTF-8@radical zh_CN.UTF-8@stroke \ zh_HK.BIG5HK \ zh_TW.BIG5 zh_TW.EUC zh_TW.UTF-8 # ON_KSH_TEST_LIST can be overridden via # $ export ON_KSH_TEST_LIST= # before $ make install # ON_KSH_TEST_LIST = $(TESTSRC)/*.sh # Boolean (true/false) flag to control whether we should make test # failures non-fatal ON_KSH_TEST_IGNORE_TESTFAILURE=false # We must wait for other things in this subdir to finish before running # the test suite, otherwise we may run into trouble that this activity # may disturb the test suite run (resulting in weird "heisenbug"-like # test failures). testshell: $(PROG) @ \ builtin basename ; \ print '# NOTE: Make sure your binaries in ROOT match your kernel!' ; \ ( \ set +o errexit ; \ export PATH="$(SRC)/cmd/ksh/$(LIBSHELLMACH):/bin:/usr/bin" ; \ printf "# which ksh='%s', ksh93='%s'\n" \ "$$(which ksh)" "$$(which ksh93)" ; \ ) ; \ if [[ "$$(isalist)" != ~(F)$(LIBSHELLMACH) ]] ; then \ printf \ "# ISA='%s' not available on this system, skipping tests...\n" \ "$(LIBSHELLMACH)" ; \ exit 0 ; \ fi ; \ print "# Libraries used:" ; \ LD_LIBRARY_PATH_64="$(ROOTLIB64)/" \ LD_LIBRARY_PATH_32="$(ROOTLIB)/" \ LD_LIBRARY_PATH="$(ROOTLIB64)/:$(ROOTLIB)/" \ /usr/bin/ldd "$(SRC)/cmd/ksh/$(LIBSHELLMACH)/ksh" ; \ print "# Running tests:" ; \ redirect 2>&1 ; \ (supported_locales="$$(/usr/bin/locale -a)" ; \ for test_lang in $(ON_KSH_TEST_LOCALES) ; do \ if [[ "$$(egrep "^$${test_lang}\$$" <<< "$${supported_locales}")" == "" ]] ; then \ printf \ "# Locale '%s' not supported, skipping tests...\n" \ "$${test_lang}" ; \ continue ; \ fi ; \ (for test_item in $(ON_KSH_TEST_LIST) ; do \ [[ "$${test_item}" == "$(TESTSRC)/builtins.sh" || \ "$${test_item}" == "$(TESTSRC)/glob.sh" || \ "$${test_item}" == "$(TESTSRC)/options.sh" ]] || \ $(ON_KSH_TEST_IGNORE_TESTFAILURE) && \ set +o errexit ; \ for mode in 'plain_script:-s' 'compiled_script:-c' ; do \ printf \ "## Running %s test: LANG='%s' script='%s', mode='%s'\n" \ "$(LIBSHELLMACH)/ksh" \ "$${test_lang}" \ "$$(basename "$${test_item}")" \ "$${mode%:*}"; \ ( \ ulimit -s 65536 ; \ test_output="$$( ( \ export \ SHELL="$(SRC)/cmd/ksh/$(LIBSHELLMACH)/ksh" \ LD_LIBRARY_PATH_64="$(ROOTLIB64)/" \ LD_LIBRARY_PATH_32="$(ROOTLIB)/" \ LD_LIBRARY_PATH="$(ROOTLIB64)/:$(ROOTLIB)/" ; \ "$${SHELL}" "$(TESTSRC)/shtests" -t "$${mode#*:}" \ LD_LIBRARY_PATH_64="$${LD_LIBRARY_PATH_64}" \ LD_LIBRARY_PATH_32="$${LD_LIBRARY_PATH_32}" \ LD_LIBRARY_PATH="$${LD_LIBRARY_PATH}" \ SHELL="$${SHELL}" \ LANG="$${test_lang}" \ LC_ALL="$${test_lang}" \ VMALLOC_OPTIONS=abort \ SHCOMP="$(ROOTBIN)/shcomp" \ "$${test_item}" \ ) 2>&1 | while read ; do \ printf "#\t%s\n" "$${REPLY}" ; \ done | tee /dev/stderr)" ; \ [[ "$${test_output}" == ~(E)test.*passed\ \[\ [[:digit:]]*\ test.*\ 0\ errors\ \] ]] || \ (print "##--------> test failed" ; exit 1) \ ) ; \ done ; \ set -o errexit ; \ done) ; \ done) # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Copyright 2021 OmniOS Community Edition (OmniOSce) Association. # # Specify the MACH we currently use to build and test ksh LIBSHELLMACH= $(MACH64) include ../../../Makefile.cmd include ../../../Makefile.cmd.64 include ../Makefile.com # Hammerhead: ksh93 is a boot-essential shell, install to /bin. # Parent ksh/Makefile creates ksh93/rksh/rksh93 hardlinks in ROOTESSBIN. ROOTPROG = $(PROG:%=$(ROOTESSBIN)/%) install: all $(ROOTPROG) include ../../../Makefile.targ # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Copyright 2010 Nexenta Systems, Inc. All rights reserved. # Copyright (c) 2018, Joyent, Inc. # Copyright 2021 OmniOS Community Edition (OmniOSce) Association. # PROG= alias ALIASPROG= \ bg \ cd \ cksum \ cmp \ comm \ command \ cut \ fc \ fg \ getopts \ hash \ jobs \ join \ kill \ paste \ print \ read \ rev \ sum \ tee \ test \ type \ ulimit \ umask \ unalias \ uniq \ wait \ wc XPG4ALIASPROG= \ alias \ bg \ cd \ command \ fc \ fg \ getopts \ hash \ jobs \ kill \ read \ test \ type \ ulimit \ umask \ unalias \ wait XPG4SH= \ sh ROOTXPG4ALIAS= \ $(XPG4SH:%=$(ROOTXPG4BIN)/%) $(XPG4ALIASPROG:%=$(ROOTXPG4BIN)/%) include ../../../Makefile.cmd # Hammerhead: SPARC Makefile.cmd.64 include removed - amd64 only # Hammerhead: Install alias + builtins to /usr/bin (same as /bin via symlink) ROOTALIASPROG= $(ALIASPROG:%=$(ROOTBIN)/%) FILEMODE= 555 CERRWARN += -Wno-parentheses # not linted SMATCH=off .KEEP_STATE: all: $(PROG) # Hammerhead: XPG4 aliases symlink to /bin/alias (3 levels up from /usr/xpg4/bin) $(XPG4ALIASPROG:%=$(ROOTXPG4BIN)/%): $(RM) $@; $(SYMLINK) ../../../bin/alias $@ $(XPG4SH:%=$(ROOTXPG4BIN)/%): $(RM) $@; $(SYMLINK) ../../bin/ksh93 $@ # Hammerhead: Builtins as hardlinks to alias in /usr/bin $(ROOTALIASPROG): $(ROOTPROG) $(RM) $@; $(LN) $(ROOTPROG) $@ # Set common AST build flags (e.g., needed to support the math stuff). include ../../Makefile.ast ASTSRC= $(C_AST)/src/cmd/ksh93 OBJECTS= \ alias.o SRCS= $(OBJECTS:%.o=%.c) LDLIBS += -lshell -lcmd -last -lumem CPPFLAGS= \ $(DTEXTDOM) $(DTS_ERRNO) \ -I$(ASTSRC)/include \ -I$(AST)/libshell/$(MACH64) \ -I$(ROOT)/usr/include/ast \ -I$(ROOT)/usr/include CFLAGS += $(ASTCFLAGS) CFLAGS64 += $(ASTCFLAGS64) # Hammerhead: Install alias to /usr/bin (= /bin via symlink) ROOTCMDDIR=$(ROOTBIN) install: all $(ROOTPROG) $(ROOTXPG4PROG) $(ROOTALIASPROG) $(ROOTXPG4ALIAS) $(PROG): $(OBJECTS) $(RM) alias $(LINK.c) $(OBJECTS) -o $@ $(LDLIBS) $(POST_PROCESS) clean clobber: rm -f $(PROG) $(OBJECTS) _msg: /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Copyright 2021 OmniOS Community Edition (OmniOSce) Association. */ /* * alias.c is a C version of the alias.sh wrapper (which links ksh * builtins to commands in /usr/bin/, e.g. calling this wrapper as * /usr/bin/alias will call the ksh "alias" builtin, running it as * /usr/bin/cut will call the ksh "cut" builtin etc. */ #include #include #include #include #include #include #undef calloc #undef free typedef struct { const char *name; int (* func)(int, char **, Shbltin_t *); } 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 */ 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 }, { "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 /* 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 }, { "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, ""); /* calls |_ast_setlocale()| */ return ((*brec->func)(argc, argv, NULL)); } /* Builtin script, originally derived from alias.sh */ static const char *script = "\n" /* Get name of builtin */ "typeset cmd=\"${0##*/}\"\n" /* * If the requested command is not an alias, load it explicitly * to make sure it is not bound to a path (those built-ins which * are mapped via shell aliases point to commands which are * "special shell built-ins" which cannot be bound to a specific * PATH element) - otherwise we may execute the wrong command * if an executable with the same name sits in a PATH element * before /usr/bin (e.g. /usr/xpg4/bin/ls would be executed * before /bin/ls if the path was something like * PATH=/usr/xpg4/bin:/usr/bin). */ "if [[ \"${cmd}\" != ~(Elr)(alias|unalias|command) ]] && " "! alias \"${cmd}\" >/dev/null 2>&1 ; then\n" "PATH='' builtin \"${cmd}\"\n" "fi\n" /* command is a keyword and needs to be handled separately */ "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; /* * Create copy of |argv| array shifted by one position to * emulate $ /usr/bin/sh ... #. * First position is set to "/usr/bin/sh" since other * values may trigger special shell modes (e.g. *rsh* will * trigger "restricted" shell mode etc.). */ 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]; /* 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)); } }