ref: b34fc2a9cfdfec3abe8d1e1831a0ebf9dc50ff07
parent: 3ec59c7b70c227846166bd1783a2859994ff9d21
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Jan 3 13:47:56 EST 2022
ape: allow exporting rc functions in environ[]
--- a/sys/src/ape/lib/ap/plan9/_envsetup.c
+++ b/sys/src/ape/lib/ap/plan9/_envsetup.c
@@ -45,7 +45,7 @@
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 @@
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;
--- a/sys/src/ape/lib/ap/plan9/execve.c
+++ b/sys/src/ape/lib/ap/plan9/execve.c
@@ -23,7 +23,7 @@
* 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 @@
* 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 @@
}
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);