xref: /titanic_41/usr/src/cmd/ksh/builtins/alias.c (revision f3f093f5e1252df53faccba99cf6d2295d6d0d58)
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 "builtin basename\n"
42 "typeset cmd=\"$(basename \"$0\")\"\n"
43 /*
44  * If the requested command is not an alias load it explicitly
45  * to make sure it is not bound to a path (those built-ins which
46  * are mapped via shell aliases point to commands which are
47  * "special shell built-ins" which cannot be bound to a specific
48  * PATH element) - otherwise we may execute the wrong command
49  * if an executable with the same name sits in a PATH element
50  * before /usr/bin (e.g. /usr/xpg4/bin/ls would be executed
51  * before /usr/bin/ls if the path was something like
52  * PATH=/usr/xpg4/bin:/usr/bin).
53  */
54 "if [[ \"${cmd}\" != ~(Elr)(alias|unalias|command) ]] && "
55 	"! alias \"${cmd}\" >/dev/null 2>&1 ; then\n"
56 "        builtin \"${cmd}\"\n"
57 "fi\n"
58 /* command is a keyword and needs to be handled separately */
59 "if [[ \"${cmd}\" == \"command\" ]] ; then\n"
60 "        command \"$@\"\n"
61 "else\n"
62 "        \"${cmd}\" \"$@\"\n"
63 "fi\n"
64 "exitval=$?";
65 
66 int
67 main(int argc, char *argv[])
68 {
69 	int i;
70 	Shell_t *shp;
71 	Namval_t *np;
72 	int exitval;
73 
74 	/*
75 	 * Create copy of |argv| array shifted by one position to
76 	 * emulate $ /usr/bin/sh <scriptname> <args1> <arg2> ... #.
77 	 * First position is set to "/usr/bin/sh" since other
78 	 * values may trigger special shell modes (e.g. *rsh* will
79 	 * trigger "restricted" shell mode etc.).
80 	 */
81 	char *xargv[argc+2];
82 	xargv[0] = "/usr/bin/sh";
83 	xargv[1] = "scriptname";
84 	for (i = 0; i < argc; i++) {
85 		xargv[i+1] = argv[i];
86 	}
87 	xargv[i+1] = NULL;
88 
89 	shp = sh_init(argc+1, xargv, 0);
90 	if (!shp)
91 		error(ERROR_exit(1), "shell initialisation failed.");
92 	(void) sh_trap(script, 0);
93 
94 	np = nv_open("exitval", shp->var_tree, 0);
95 	if (!np)
96 		error(ERROR_exit(1), "variable %s not found.", "exitval");
97 	exitval = (int)nv_getnum(np);
98 	nv_close(np);
99 
100 	return (exitval);
101 }
102