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