13e12c5d1SDavid du Colombier #include "lib.h"
23e12c5d1SDavid du Colombier #include <unistd.h>
33e12c5d1SDavid du Colombier #include <errno.h>
43e12c5d1SDavid du Colombier #include <string.h>
5219b2ee8SDavid du Colombier #include <signal.h>
63e12c5d1SDavid du Colombier #include "sys9.h"
73e12c5d1SDavid du Colombier
83e12c5d1SDavid du Colombier extern char **environ;
93e12c5d1SDavid du Colombier
103e12c5d1SDavid du Colombier int
execve(const char * name,const char * argv[],const char * envp[])113e12c5d1SDavid du Colombier execve(const char *name, const char *argv[], const char *envp[])
123e12c5d1SDavid du Colombier {
133e12c5d1SDavid du Colombier int n, f, i;
143e12c5d1SDavid du Colombier char **e, *ss, *se;
153e12c5d1SDavid du Colombier Fdinfo *fi;
16219b2ee8SDavid du Colombier unsigned long flags;
179a747e4fSDavid du Colombier char nam[256+5];
183e12c5d1SDavid du Colombier char buf[1000];
193e12c5d1SDavid du Colombier
20219b2ee8SDavid du Colombier _RFORK(RFCENVG);
213e12c5d1SDavid du Colombier /*
223e12c5d1SDavid du Colombier * To pass _fdinfo[] across exec, put lines like
233e12c5d1SDavid du Colombier * fd flags oflags
243e12c5d1SDavid du Colombier * in $_fdinfo (for open fd's)
253e12c5d1SDavid du Colombier */
263e12c5d1SDavid du Colombier
273e12c5d1SDavid du Colombier f = _CREATE("#e/_fdinfo", OWRITE, 0666);
283e12c5d1SDavid du Colombier ss = buf;
293e12c5d1SDavid du Colombier for(n = 0; n<OPEN_MAX; n++){
303e12c5d1SDavid du Colombier fi = &_fdinfo[n];
31219b2ee8SDavid du Colombier flags = fi->flags;
32219b2ee8SDavid du Colombier if(flags&FD_CLOEXEC){
333e12c5d1SDavid du Colombier _CLOSE(n);
343e12c5d1SDavid du Colombier fi->flags = 0;
353e12c5d1SDavid du Colombier fi->oflags = 0;
36219b2ee8SDavid du Colombier }else if(flags&FD_ISOPEN){
373e12c5d1SDavid du Colombier ss = _ultoa(ss, n);
383e12c5d1SDavid du Colombier *ss++ = ' ';
39219b2ee8SDavid du Colombier ss = _ultoa(ss, flags);
403e12c5d1SDavid du Colombier *ss++ = ' ';
413e12c5d1SDavid du Colombier ss = _ultoa(ss, fi->oflags);
423e12c5d1SDavid du Colombier *ss++ = '\n';
433e12c5d1SDavid du Colombier if(ss-buf < sizeof(buf)-50){
443e12c5d1SDavid du Colombier _WRITE(f, buf, ss-buf);
453e12c5d1SDavid du Colombier ss = buf;
463e12c5d1SDavid du Colombier }
473e12c5d1SDavid du Colombier }
483e12c5d1SDavid du Colombier }
493e12c5d1SDavid du Colombier if(ss > buf)
503e12c5d1SDavid du Colombier _WRITE(f, buf, ss-buf);
513e12c5d1SDavid du Colombier _CLOSE(f);
52219b2ee8SDavid du Colombier /*
53219b2ee8SDavid du Colombier * To pass _sighdlr[] across exec, set $_sighdlr
54219b2ee8SDavid du Colombier * to list of blank separated fd's that have
55219b2ee8SDavid du Colombier * SIG_IGN (the rest will be SIG_DFL).
56219b2ee8SDavid du Colombier * We write the variable, even if no signals
57219b2ee8SDavid du Colombier * are ignored, in case the current value of the
58219b2ee8SDavid du Colombier * variable ignored some.
59219b2ee8SDavid du Colombier */
60219b2ee8SDavid du Colombier f = _CREATE("#e/_sighdlr", OWRITE, 0666);
61219b2ee8SDavid du Colombier if(f >= 0){
62219b2ee8SDavid du Colombier ss = buf;
63*781103c4SDavid du Colombier for(i = 0; i <=MAXSIG && ss < &buf[sizeof(buf)]-5; i++) {
64219b2ee8SDavid du Colombier if(_sighdlr[i] == SIG_IGN) {
65219b2ee8SDavid du Colombier ss = _ultoa(ss, i);
66219b2ee8SDavid du Colombier *ss++ = ' ';
67219b2ee8SDavid du Colombier }
68219b2ee8SDavid du Colombier }
69219b2ee8SDavid du Colombier _WRITE(f, buf, ss-buf);
70219b2ee8SDavid du Colombier _CLOSE(f);
71219b2ee8SDavid du Colombier }
72219b2ee8SDavid du Colombier if(envp){
733e12c5d1SDavid du Colombier strcpy(nam, "#e/");
74*781103c4SDavid du Colombier for(e = (char **)envp; (ss = *e); e++) {
753e12c5d1SDavid du Colombier se = strchr(ss, '=');
763e12c5d1SDavid du Colombier if(!se || ss==se)
773e12c5d1SDavid du Colombier continue; /* what is name? value? */
783e12c5d1SDavid du Colombier n = se-ss;
799a747e4fSDavid du Colombier if(n >= sizeof(nam)-3)
809a747e4fSDavid du Colombier n = sizeof(nam)-3-1;
813e12c5d1SDavid du Colombier memcpy(nam+3, ss, n);
823e12c5d1SDavid du Colombier nam[3+n] = 0;
833e12c5d1SDavid du Colombier f = _CREATE(nam, OWRITE, 0666);
843e12c5d1SDavid du Colombier if(f < 0)
853e12c5d1SDavid du Colombier continue;
863e12c5d1SDavid du Colombier se++; /* past = */
873e12c5d1SDavid du Colombier n = strlen(se);
883e12c5d1SDavid du Colombier /* temporarily decode nulls (see _envsetup()) */
893e12c5d1SDavid du Colombier for(i=0; i < n; i++)
903e12c5d1SDavid du Colombier if(se[i] == 1)
913e12c5d1SDavid du Colombier se[i] = 0;
923e12c5d1SDavid du Colombier _WRITE(f, se, n);
933e12c5d1SDavid du Colombier /* put nulls back */
943e12c5d1SDavid du Colombier for(i=0; i < n; i++)
953e12c5d1SDavid du Colombier if(se[i] == 0)
963e12c5d1SDavid du Colombier se[i] = 1;
973e12c5d1SDavid du Colombier _CLOSE(f);
983e12c5d1SDavid du Colombier }
993e12c5d1SDavid du Colombier }
1003e12c5d1SDavid du Colombier n = _EXEC(name, argv);
1013e12c5d1SDavid du Colombier _syserrno();
1023e12c5d1SDavid du Colombier return n;
1033e12c5d1SDavid du Colombier }
104