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[NAMELEN+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, n=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 = 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 > NAMELEN-1) 80 n = NAMELEN-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