xref: /plan9-contrib/sys/src/ape/lib/ap/plan9/execve.c (revision 781103c4074deb8af160e8a0da2742ba6b29dc2b)
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