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
execve(const char * name,const char * argv[],const char * envp[])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 }
104