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.
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.
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]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1988 AT&T */
28 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI"
33 * execlp(name, arg,...,0) (like execl, but does path search)
34 * execvp(name, argv) (like execv, but does path search)
37 #pragma weak _execlp = execlp
38 #pragma weak _execvp = execvp
41 #include <sys/types.h>
50 static const char *execat(const char *, const char *, char *);
52 extern int __xpg4
; /* defined in xpg4.c; 0 if not xpg4-compiled program */
56 execlp(const char *name
, const char *arg0
, ...)
66 * count the number of arguments in the variable argument list
67 * and allocate an argument vector for them on the stack,
68 * adding space for a terminating null pointer at the end
69 * and one additional space for argv[0] which is no longer
70 * counted by the varargs loop.
75 while (va_arg(args
, char *) != (char *)0)
81 * load the arguments in the variable argument list
82 * into the argument vector and add the terminating null pointer
86 /* workaround for bugid 1242839 */
87 argvec
= alloca((size_t)((nargs
+ 2) * sizeof (char *)));
88 nextarg
= va_arg(args
, char *);
90 *argp
++ = (char *)arg0
;
91 while (nargs
-- && nextarg
!= (char *)0) {
94 nextarg
= va_arg(args
, char *);
103 err
= execvp(name
, argvec
);
108 execvp(const char *name
, char *const *argv
)
111 char fname
[PATH_MAX
+2];
115 unsigned etxtbsy
= 1;
118 static const char *sun_path
= "/bin/sh";
119 static const char *xpg4_path
= "/usr/xpg4/bin/sh";
120 static const char *shell
= "sh";
126 if ((pathstr
= getenv("PATH")) == NULL
) {
128 * XPG4: pathstr is equivalent to CSPATH, except that
129 * :/usr/sbin is appended when root, and pathstr must end
130 * with a colon when not root. Keep these paths in sync
131 * with CSPATH in confstr.c. Note that pathstr must end
132 * with a colon when not root so that when name doesn't
133 * contain '/', the last call to execat() will result in an
134 * attempt to execv name from the current directory.
136 if (geteuid() == 0 || getuid() == 0) {
137 if (__xpg4
== 0) { /* not XPG4 */
138 pathstr
= "/usr/sbin:/usr/ccs/bin:/usr/bin";
139 } else { /* XPG4 (CSPATH + /usr/sbin) */
140 pathstr
= "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:"
141 "/opt/SUNWspro/bin:/usr/sbin";
144 if (__xpg4
== 0) { /* not XPG4 */
145 pathstr
= "/usr/ccs/bin:/usr/bin:";
146 } else { /* XPG4 (CSPATH) */
147 pathstr
= "/usr/xpg4/bin:/usr/ccs/bin:"
148 "/usr/bin:/opt/SUNWspro/bin:";
152 cp
= strchr(name
, '/')? (const char *)"": pathstr
;
155 cp
= execat(cp
, name
, fname
);
158 * 4025035 and 4038378
159 * if a filename begins with a "-" prepend "./" so that
160 * the shell can't interpret it as an option
163 size_t size
= strlen(fname
) + 1;
164 if ((size
+ 2) > sizeof (fname
)) {
168 (void) memmove(fname
+ 2, fname
, size
);
172 (void) execv(fname
, argv
);
175 if (__xpg4
== 0) { /* not XPG4 */
176 shpath
= (char *)sun_path
;
178 shpath
= (char *)xpg4_path
;
180 newargs
[0] = (char *)shell
;
182 for (i
= 1; (newargs
[i
+ 1] = argv
[i
]) != NULL
; ++i
) {
188 (void) execv((const char *)shpath
, newargs
);
193 (void) sleep(etxtbsy
);
210 execat(const char *s1
, const char *s2
, char *si
)
213 int cnt
= PATH_MAX
+ 1; /* number of characters in s2 */
216 while (*s1
&& *s1
!= ':') {
223 if (si
!= s
&& cnt
> 0) {
227 while (*s2
&& cnt
> 0) {
232 return (*s1
? ++s1
: 0);