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