Files
oasis-linux-mirror/pkg/rc/patch/0004-keep-PATH-and-path-in-sync.patch
T
2026-05-01 19:40:12 -07:00

194 lines
3.5 KiB
Diff

From bc1444426b57c30af71af6a26fa1674984d414a4 Mon Sep 17 00:00:00 2001
From: hovercats <hovercatswithlasereyes@protonmail.com>
Date: Sat, 25 Apr 2026 16:54:31 +0200
Subject: [PATCH] keep $PATH and $path in sync
---
exec.c | 12 ++++----
fns.h | 1 +
rc.h | 1 +
var.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
4 files changed, 99 insertions(+), 8 deletions(-)
diff --git a/exec.c b/exec.c
index ce9872a..987960d 100644
--- a/exec.c
+++ b/exec.c
@@ -265,6 +265,7 @@ main(int argc, char *argv[])
Trapinit();
Vinit();
inttoascii(num, mypid = getpid());
+ pathinit();
setvar("pid", newword(num, (word *)0));
setvar("cflag", flag['c']?newword(flag['c'][0], (word *)0)
:(word *)0);
@@ -758,16 +759,15 @@ void
Xassign(void)
{
var *v;
+ word *w;
- if(count(runq->argv->words)!=1){
+ w = Poplist();
+ if(count(w)!=1){
Xerror1("= variable name not singleton!");
return;
}
- v = vlook(runq->argv->words->word);
- poplist();
- freewords(v->val);
- v->val = Poplist();
- v->changed = 1;
+ setvar(w->word, Poplist());
+ freewords(w);
}
/*
diff --git a/fns.h b/fns.h
index 1644d1e..a99f6fa 100644
--- a/fns.h
+++ b/fns.h
@@ -49,6 +49,7 @@ int mapfd(int);
int match(char*, char*, int);
char* makepath(char*, char*);
void panic(char*, int);
+void pathinit(void);
void pfln(io*, char*, int);
void poplist(void);
void popword(void);
diff --git a/rc.h b/rc.h
index a688663..3f48cce 100644
--- a/rc.h
+++ b/rc.h
@@ -117,6 +117,7 @@ struct var{
int pc; /* pc of start of function */
char fnchanged;
char changed;
+ void (*changefn)(var*);
char name[];
};
var *vlook(char*), *gvlook(char*), *newvar(char*, var*);
diff --git a/var.c b/var.c
index 73b01fa..e132a7b 100644
--- a/var.c
+++ b/var.c
@@ -70,6 +70,7 @@ newvar(char *name, var *next)
v->fn = 0;
v->changed = 0;
v->fnchanged = 0;
+ v->changefn = 0;
return v;
}
@@ -92,13 +93,21 @@ vlook(char *name)
return gvlook(name);
}
-void
-setvar(char *name, word *val)
+static void
+setvar_(char *name, word *val, int callfn)
{
var *v = vlook(name);
freewords(v->val);
v->val = val;
v->changed = 1;
+ if(callfn && v->changefn)
+ v->changefn(v);
+}
+
+void
+setvar(char *name, word *val)
+{
+ setvar_(name, val, 1);
}
void
@@ -107,3 +116,83 @@ freevar(var *v)
freewords(v->val);
free(v);
}
+
+static void
+bigpath(var *v)
+{
+ /* convert $PATH to $path */
+ char *p, *q;
+ word **l, *w;
+
+ if(v->val == 0){
+ setvar_("path", 0, 0);
+ return;
+ }
+ p = v->val->word;
+ w = 0;
+ l = &w;
+ /*
+ * Doesn't handle escaped colon nonsense.
+ */
+ if(p[0] == 0)
+ p = 0;
+ while(p){
+ q = strchr(p, ':');
+ if(q)
+ *q = 0;
+ *l = newword(p[0] ? p : ".", 0);
+ l = &(*l)->next;
+ if(q){
+ *q = ':';
+ p = q+1;
+ }else
+ p = 0;
+ }
+ setvar_("path", w, 0);
+}
+
+static char *
+list2strcolon(word *words)
+{
+ char *value, *s, *t;
+ int len = 0;
+ word *ap;
+ for(ap = words;ap;ap = ap->next)
+ len+=1+strlen(ap->word);
+ value = emalloc(len+1);
+ s = value;
+ for(ap = words;ap;ap = ap->next){
+ for(t = ap->word;*t;) *s++=*t++;
+ *s++=':';
+ }
+ if(s==value)
+ *s='\0';
+ else s[-1]='\0';
+ return value;
+}
+
+static void
+littlepath(var *v)
+{
+ /* convert $path to $PATH */
+ char *p;
+ word *w;
+
+ p = list2strcolon(v->val);
+ w = new(word);
+ w->word = p;
+ w->next = 0;
+ setvar_("PATH", w, 1); /* 1: recompute $path to expose colon problems */
+}
+
+void
+pathinit(void)
+{
+ var *v;
+
+ v = gvlook("path");
+ v->changefn = littlepath;
+ v = gvlook("PATH");
+ v->changefn = bigpath;
+ bigpath(v);
+}
--
2.49.0