Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "lib.h"
2
#include <unistd.h>
3
#include <errno.h>
4
#include <string.h>
5
#include <signal.h>
6
#include "sys9.h"
7
 
8
extern char **environ;
9
 
10
int
11
execve(const char *name, const char *argv[], const char *envp[])
12
{
13
	int n, f, i;
14
	char **e, *ss, *se;
15
	Fdinfo *fi;
16
	unsigned long flags;
17
	char nam[256+5];
18
	char buf[1000];
19
 
20
	_RFORK(RFCENVG);
21
	/*
22
	 * To pass _fdinfo[] across exec, put lines like
23
	 *   fd flags oflags
24
	 * in $_fdinfo (for open fd's)
25
	 */
26
 
27
	f = _CREATE("#e/_fdinfo", OWRITE, 0666);
28
	ss = buf;
29
	for(n = 0; n<OPEN_MAX; n++){
30
		fi = &_fdinfo[n];
31
		flags = fi->flags;
32
		if(flags&FD_CLOEXEC){
33
			_CLOSE(n);
34
			fi->flags = 0;
35
			fi->oflags = 0;
36
		}else if(flags&FD_ISOPEN){
37
			ss = _ultoa(ss, n);
38
			*ss++ = ' ';
39
			ss = _ultoa(ss, flags);
40
			*ss++ = ' ';
41
			ss = _ultoa(ss, fi->oflags);
42
			*ss++ = '\n';
43
			if(ss-buf < sizeof(buf)-50){
44
				_WRITE(f, buf, ss-buf);
45
				ss = buf;
46
			}
47
		}
48
	}
49
	if(ss > buf)
50
		_WRITE(f, buf, ss-buf);
51
	_CLOSE(f);
52
	/*
53
	 * To pass _sighdlr[] across exec, set $_sighdlr
54
	 * to list of blank separated fd's that have
55
	 * SIG_IGN (the rest will be SIG_DFL).
56
	 * We write the variable, even if no signals
57
	 * are ignored, in case the current value of the
58
	 * variable ignored some.
59
	 */
60
	f = _CREATE("#e/_sighdlr", OWRITE, 0666);
61
	if(f >= 0){
62
		ss = buf;
63
		for(i = 0; i <=MAXSIG && ss < &buf[sizeof(buf)]-5; i++) {
64
			if(_sighdlr[i] == SIG_IGN) {
65
				ss = _ultoa(ss, i);
66
				*ss++ = ' ';
67
			}
68
		}
69
		_WRITE(f, buf, ss-buf);
70
		_CLOSE(f);
71
	}
72
	if(envp){
73
		strcpy(nam, "#e/");
74
		for(e = (char **)envp; (ss = *e); e++) {
75
			se = strchr(ss, '=');
76
			if(!se || ss==se)
77
				continue;	/* what is name? value? */
78
			n = se-ss;
79
			if(n >= sizeof(nam)-3)
80
				n = sizeof(nam)-3-1;
81
			memcpy(nam+3, ss, n);
82
			nam[3+n] = 0;
83
			f = _CREATE(nam, OWRITE, 0666);
84
			if(f < 0)
85
				continue;
86
			se++; /* past = */
87
			n = strlen(se);
88
			/* temporarily decode nulls (see _envsetup()) */
89
			for(i=0; i < n; i++)
90
				if(se[i] == 1)
91
					se[i] = 0;
92
			_WRITE(f, se, n);
93
			/* put nulls back */
94
			for(i=0; i < n; i++)
95
				if(se[i] == 0)
96
					se[i] = 1;
97
			_CLOSE(f);
98
		}
99
	}
100
	n = _EXEC(name, argv);
101
	_syserrno();
102
	return n;
103
}