xref: /csrg-svn/lib/libc/gen/exec.c (revision 46572)
1 #if defined(LIBC_SCCS) && !defined(lint)
2 static char sccsid[] = "@(#)exec.c	5.4 (Berkeley) 02/23/91";
3 #endif LIBC_SCCS and not lint
4 
5 /*
6  *	execlp(name, arg,...,0)	(like execl, but does path search)
7  *	execvp(name, argv)	(like execv, but does path search)
8  */
9 #include <errno.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13 
14 static	char shell[] =	"/bin/sh";
15 
16 int
17 execlp(name, argv)
18 const char *name, *argv;
19 {
20 	return(execvp(name, &argv));
21 }
22 
23 int
24 execvp(name, argv)
25 const char *name;
26 char * const *argv;
27 {
28 	char *pathstr;
29 	register char *cp;
30 	char fname[128];
31 	char *newargs[256], *execat();
32 	int i;
33 	register unsigned etxtbsy = 1;
34 	register eacces = 0;
35 
36 	if ((pathstr = getenv("PATH")) == NULL)
37 		pathstr = ":/bin:/usr/bin";
38 	cp = index(name, '/')? "": pathstr;
39 
40 	do {
41 		cp = execat(cp, name, fname);
42 	retry:
43 		execv(fname, argv);
44 		switch(errno) {
45 		case ENOEXEC:
46 			newargs[0] = "sh";
47 			newargs[1] = fname;
48 			for (i=1; newargs[i+1]=argv[i]; i++) {
49 				if (i>=254) {
50 					errno = E2BIG;
51 					return(-1);
52 				}
53 			}
54 			execv(shell, newargs);
55 			return(-1);
56 		case ETXTBSY:
57 			if (++etxtbsy > 5)
58 				return(-1);
59 			sleep(etxtbsy);
60 			goto retry;
61 		case EACCES:
62 			eacces++;
63 			break;
64 		case ENOMEM:
65 		case E2BIG:
66 			return(-1);
67 		}
68 	} while (cp);
69 	if (eacces)
70 		errno = EACCES;
71 	return(-1);
72 }
73 
74 static char *
75 execat(s1, s2, si)
76 register char *s1, *s2;
77 char *si;
78 {
79 	register char *s;
80 
81 	s = si;
82 	while (*s1 && *s1 != ':')
83 		*s++ = *s1++;
84 	if (si != s)
85 		*s++ = '/';
86 	while (*s2)
87 		*s++ = *s2++;
88 	*s = '\0';
89 	return(*s1? ++s1: 0);
90 }
91