/* execve.c: an execve() for geriatric unices without #! */
NOTE: this file depends on a hack in footobar.c which places two free spots before
av[][] so that execve does not have to call malloc.
#define giveupif(x) { if (x) goto fail; }
extern int my_execve(const char *path
, const char **av
, const char **ev
) {
int fd
, len
, fst
, snd
, end
;
char pb
[256]; /* arbitrary but generous limit */
fd
= rc_open(path
, rFrom
);
len
= read(fd
, pb
, sizeof pb
);
/* reject scripts which don't begin with #! */
giveupif(len
<= 0 || pb
[0] != '#' || pb
[1] != '!');
for (fst
= 2; fst
< len
&& (pb
[fst
] == ' ' || pb
[fst
] == '\t'); fst
++)
; /* skip leading whitespace */
for (snd
= fst
; snd
< len
&& pb
[snd
] != ' ' && pb
[snd
] != '\t' && pb
[snd
] != '\n'; snd
++)
noarg
= (pb
[snd
] == '\n');
pb
[snd
++] = '\0'; /* null terminate the first arg */
while (snd
< len
&& (pb
[snd
] == ' ' || pb
[snd
] == '\t'))
snd
++; /* skip whitespace to second arg */
noarg
= (pb
[snd
] == '\n'); /* could have trailing whitespace after only one arg */
for (end
= snd
; end
< len
&& pb
[end
] != ' ' && pb
[end
] != '\t' && pb
[end
] != '\n'; end
++)
; /* skip to the end of the second arg */
pb
[end
] = '\0'; /* null terminate the first arg */
} else { /* else check for a spurious third arg */
while (end
< len
&& (pb
[end
] == ' ' || pb
[end
] == '\t'))
giveupif(end
== len
|| pb
[end
] != '\n');