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