ape: allow exporting rc functions in environ[]

This commit is contained in:
cinap_lenrek 2022-01-03 18:47:56 +00:00
parent 3ec59c7b70
commit b34fc2a9cf
2 changed files with 68 additions and 36 deletions

View file

@ -45,7 +45,7 @@ _envsetup(void)
nohandle = 0;
fdinited = 0;
cnt = 0;
dfd = _OPEN("/env", OREAD);
dfd = _OPEN("/env", OREAD|OCEXEC);
if(dfd < 0)
goto done;
psize = Envhunk;
@ -62,21 +62,36 @@ _envsetup(void)
ps = realloc(ps, psize);
p = ps + i;
}
strcpy(p, "/env/");
memcpy(p, "/env/", 5);
memcpy(p+5, d9->name, n+1);
f = _OPEN(p, OREAD);
memset(p, 0, n+6);
f = _OPEN(p, OREAD|OCEXEC);
if(f < 0)
continue;
if(n > 3 && memcmp(d9->name, "fn#", 3)==0){
if(m > 3
&& _READ(f, p+3, m) == m
&& memcmp(p+3, "fn ", 3) == 0
&& memcmp(p+3+3, d9->name+3, n-3) == 0
&& memchr(p+3+n, '{', m-n) != 0){
memcpy(p, "#()", 3);
p[3+m] = '\0';
p += m+4;
cnt++;
}
_CLOSE(f);
continue;
}
memcpy(p, d9->name, n);
p[n] = '=';
if(f < 0 || _READ(f, p+n+1, m) != m)
if(_READ(f, p+n+1, m) != m)
m = 0;
_CLOSE(f);
if(p[n+m] == 0)
if(p[n+m]=='\0')
m--;
for(i=0; i<m; i++)
if(p[n+1+i] == 0)
p[n+1+i] = 1;
p[n+1+m] = 0;
if(p[n+1+i]=='\0')
p[n+1+i] = '\1';
p[n+1+m] = '\0';
if(strcmp(d9->name, "_fdinfo") == 0) {
_fdinit(p+n+1, p+n+1+m);
fdinited = 1;

View file

@ -23,7 +23,7 @@ execve(const char *name, const char *argv[], const char *envp[])
* in $_fdinfo (for open fd's)
*/
f = _CREATE("/env/_fdinfo", OWRITE, 0666);
f = _CREATE("/env/_fdinfo", OWRITE|OCEXEC, 0666);
ss = buf;
for(i = 0; i<OPEN_MAX; i++){
if(i == f)
@ -65,7 +65,7 @@ execve(const char *name, const char *argv[], const char *envp[])
* are ignored, in case the current value of the
* variable ignored some.
*/
f = _CREATE("/env/_sighdlr", OWRITE, 0666);
f = _CREATE("/env/_sighdlr", OWRITE|OCEXEC, 0666);
if(f >= 0){
ss = buf;
for(i = 0; i <=MAXSIG; i++) {
@ -86,32 +86,49 @@ execve(const char *name, const char *argv[], const char *envp[])
}
if(envp){
for(e = (char**)envp; (ss = *e); e++) {
se = strchr(ss, '=');
if(!se || ss==se)
continue; /* what is name? value? */
n = se-ss;
if(n >= sizeof(buf)-5)
continue; /* name too long */
strcpy(buf, "/env/");
memcpy(buf+5, ss, n);
buf[5+n] = 0;
f = _CREATE(buf, OWRITE, 0666);
if(f < 0)
continue;
ss = ++se; /* past = */
se += strlen(ss);
while((n = (se - ss)) > 0){
if(n > sizeof(buf))
n = sizeof(buf);
/* decode nulls (see _envsetup()) */
for(i=0; i<n; i++)
if((buf[i] = ss[i]) == 1)
buf[i] = 0;
if(_WRITE(f, buf, n) != n)
break;
ss += n;
if(strncmp(ss, "#()fn ", 6)==0){
if((se = strchr(ss+6, '{'))==0)
continue;
while(se[-1]==' ') se--;
n = se-(ss+6);
if(n <= 0 || n >= sizeof(buf)-8)
continue; /* name too long */
memcpy(buf, "/env/fn#", 8);
memcpy(buf+8, ss+6, n);
buf[8+n] = '\0';
f = _CREATE(buf, OWRITE|OCEXEC, 0666);
if(f < 0)
continue;
ss += 3; /* past #() */
_WRITE(f, ss, strlen(ss));
_CLOSE(f);
} else {
if((se = strchr(ss, '='))==0)
continue;
n = se-ss;
if(n <= 0 || n >= sizeof(buf)-5)
continue; /* name too long */
memcpy(buf, "/env/", 5);
memcpy(buf+5, ss, n);
buf[5+n] = '\0';
f = _CREATE(buf, OWRITE|OCEXEC, 0666);
if(f < 0)
continue;
ss = ++se; /* past = */
se += strlen(se);
while((n = (se - ss)) > 0){
if(n > sizeof(buf))
n = sizeof(buf);
/* decode nulls (see _envsetup()) */
for(i=0; i<n; i++)
if((buf[i] = ss[i]) == 1)
buf[i] = 0;
if(_WRITE(f, buf, n) != n)
break;
ss += n;
}
_CLOSE(f);
}
_CLOSE(f);
}
}
n = _EXEC(name, argv);