BSD 4_4_Lite1 development
[unix-history] / usr / src / contrib / rc-1.4 / execve.c
CommitLineData
9d25673b
C
1/* execve.c: an execve() for geriatric unices without #! */
2
3/*
4 NOTE: this file depends on a hack in footobar.c which places two free spots before
5 av[][] so that execve does not have to call malloc.
6*/
7
8#include <errno.h>
9#include "rc.h"
10
11#define giveupif(x) { if (x) goto fail; }
12
13extern int my_execve(const char *path, const char **av, const char **ev) {
14 int fd, len, fst, snd, end;
15 bool noarg;
16 char pb[256]; /* arbitrary but generous limit */
17 execve(path, av, ev);
18 if (errno != ENOEXEC)
19 return -1;
20 fd = rc_open(path, rFrom);
21 giveupif(fd < 0);
22 len = read(fd, pb, sizeof pb);
23 close(fd);
24 /* reject scripts which don't begin with #! */
25 giveupif(len <= 0 || pb[0] != '#' || pb[1] != '!');
26 for (fst = 2; fst < len && (pb[fst] == ' ' || pb[fst] == '\t'); fst++)
27 ; /* skip leading whitespace */
28 giveupif(fst == len);
29 for (snd = fst; snd < len && pb[snd] != ' ' && pb[snd] != '\t' && pb[snd] != '\n'; snd++)
30 ; /* skip first arg */
31 giveupif(snd == len);
32 noarg = (pb[snd] == '\n');
33 pb[snd++] = '\0'; /* null terminate the first arg */
34 if (!noarg) {
35 while (snd < len && (pb[snd] == ' ' || pb[snd] == '\t'))
36 snd++; /* skip whitespace to second arg */
37 giveupif(snd == len);
38 noarg = (pb[snd] == '\n'); /* could have trailing whitespace after only one arg */
39 if (!noarg) {
40 for (end = snd; end < len && pb[end] != ' ' && pb[end] != '\t' && pb[end] != '\n'; end++)
41 ; /* skip to the end of the second arg */
42 giveupif(end == len);
43 if (pb[end] == '\n') {
44 pb[end] = '\0'; /* null terminate the first arg */
45 } else { /* else check for a spurious third arg */
46 pb[end++] = '\0';
47 while (end < len && (pb[end] == ' ' || pb[end] == '\t'))
48 end++;
49 giveupif(end == len || pb[end] != '\n');
50 }
51 }
52 }
53 *av = path;
54 if (!noarg)
55 *--av = pb + snd;
56 *--av = pb + fst;
57 execve(*av, av, ev);
58 return -1;
59fail: errno = ENOEXEC;
60 return -1;
61}