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