1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * alias.c is a C version of the alias.sh wrapper (which links ksh 29 * builtins to commands in /usr/bin/, e.g. calling this wrapper as 30 * /usr/bin/alias will call the ksh "alias" builtin, running it as 31 * /usr/bin/cut will call the ksh "cut" builtin etc. 32 */ 33 34 #include <shell.h> 35 #include <nval.h> 36 #include <stdio.h> 37 38 /* Builtin script, original derived from alias.sh */ 39 static const char *script = "\n" 40 /* Get name of builtin */ 41 "typeset cmd=\"${0##*/}\"\n" 42 /* 43 * If the requested command is not an alias load it explicitly 44 * to make sure it is not bound to a path (those built-ins which 45 * are mapped via shell aliases point to commands which are 46 * "special shell built-ins" which cannot be bound to a specific 47 * PATH element) - otherwise we may execute the wrong command 48 * if an executable with the same name sits in a PATH element 49 * before /usr/bin (e.g. /usr/xpg4/bin/ls would be executed 50 * before /usr/bin/ls if the path was something like 51 * PATH=/usr/xpg4/bin:/usr/bin). 52 */ 53 "if [[ \"${cmd}\" != ~(Elr)(alias|unalias|command) ]] && " 54 "! alias \"${cmd}\" >/dev/null 2>&1 ; then\n" 55 "builtin \"${cmd}\"\n" 56 "fi\n" 57 /* command is a keyword and needs to be handled separately */ 58 "if [[ \"${cmd}\" == \"command\" ]] ; then\n" 59 "command \"$@\"\n" 60 "else\n" 61 "\"${cmd}\" \"$@\"\n" 62 "fi\n" 63 "exitval=$?"; 64 65 int 66 main(int argc, char *argv[]) 67 { 68 int i; 69 Shell_t *shp; 70 Namval_t *np; 71 int exitval; 72 73 /* 74 * Create copy of |argv| array shifted by one position to 75 * emulate $ /usr/bin/sh <scriptname> <args1> <arg2> ... #. 76 * First position is set to "/usr/bin/sh" since other 77 * values may trigger special shell modes (e.g. *rsh* will 78 * trigger "restricted" shell mode etc.). 79 */ 80 char *xargv[argc+2]; 81 xargv[0] = "/usr/bin/sh"; 82 xargv[1] = "scriptname"; 83 for (i = 0; i < argc; i++) { 84 xargv[i+1] = argv[i]; 85 } 86 xargv[i+1] = NULL; 87 88 shp = sh_init(argc+1, xargv, 0); 89 if (!shp) 90 error(ERROR_exit(1), "shell initialisation failed."); 91 (void) sh_trap(script, 0); 92 93 np = nv_open("exitval", shp->var_tree, 0); 94 if (!np) 95 error(ERROR_exit(1), "variable %s not found.", "exitval"); 96 exitval = (int)nv_getnum(np); 97 nv_close(np); 98 99 return (exitval); 100 } 101