Home | History | Annotate | Download | only in common
      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, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*      Copyright (c) 1984 AT&T */
     28 /*        All Rights Reserved   */
     29 
     30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     31 
     32 /*LINTLIBRARY*/
     33 /*
     34  *	execlp(name, arg,...,0)	(like execl, but does path search)
     35  *	execvp(name, argv)	(like execv, but does path search)
     36  */
     37 #include <errno.h>
     38 #include <sys/param.h>
     39 #include <stdarg.h>
     40 #include <string.h>
     41 #include <stdlib.h>
     42 #include <unistd.h>
     43 
     44 static char *execat(char *, char *, char *);
     45 static char *shell = "/bin/sh";
     46 
     47 int
     48 execlp(char *name, ...)
     49 {
     50 	va_list	args;
     51 	int	r;
     52 
     53 	va_start(args, name);
     54 	r = execvp(name, (char **)args);
     55 	va_end(args);
     56 
     57 	return (r);
     58 }
     59 
     60 int
     61 execvp(char *name, char **argv)
     62 {
     63 	char	*pathstr;
     64 	char	fname[MAXPATHLEN];
     65 	char	*newargs[256];
     66 	int	i;
     67 	char	*cp;
     68 	unsigned etxtbsy = 1;
     69 	int	eacces = 0;
     70 
     71 	if ((pathstr = getenv("PATH")) == NULL)
     72 		pathstr = ":/usr/ucb:/bin:/usr/bin";
     73 	cp = strchr(name, '/') ? "": pathstr;
     74 
     75 	do {
     76 		cp = execat(cp, name, fname);
     77 	retry:
     78 		(void) execv(fname, argv);
     79 		switch (errno) {
     80 		case ENOEXEC:
     81 			newargs[0] = "sh";
     82 			newargs[1] = fname;
     83 			for (i = 1; (newargs[i+1] = argv[i]) != NULL; ++i) {
     84 				if (i >= 254) {
     85 					errno = E2BIG;
     86 					return(-1);
     87 				}
     88 			}
     89 			(void) execv(shell, newargs);
     90 			return (-1);
     91 		case ETXTBSY:
     92 			if (++etxtbsy > 5)
     93 				return (-1);
     94 			(void) sleep(etxtbsy);
     95 			goto retry;
     96 		case EACCES:
     97 			++eacces;
     98 			break;
     99 		case ENOMEM:
    100 		case E2BIG:
    101 		case EFAULT:
    102 			return (-1);
    103 		}
    104 	} while (cp);
    105 	if (eacces)
    106 		errno = EACCES;
    107 	return (-1);
    108 }
    109 
    110 static char *
    111 execat(char *s1, char *s2, char *si)
    112 {
    113 	char	*s;
    114 	char	*end;
    115 
    116 	s = si;
    117 	end = s + MAXPATHLEN;
    118 	while (*s1 && *s1 != ':' && s < end)
    119 		*s++ = *s1++;
    120 	if (si != s && s < end)
    121 		*s++ = '/';
    122 	while (*s2 && s < end)
    123 		*s++ = *s2++;
    124 	*s = '\0';
    125 	return (*s1 ? ++s1: 0);
    126 }
    127