0004-keep-PATH-and-path-in-sync.patch (3576B)
1 From bc1444426b57c30af71af6a26fa1674984d414a4 Mon Sep 17 00:00:00 2001 2 From: hovercats <hovercatswithlasereyes@protonmail.com> 3 Date: Sat, 25 Apr 2026 16:54:31 +0200 4 Subject: [PATCH] keep $PATH and $path in sync 5 6 --- 7 exec.c | 12 ++++---- 8 fns.h | 1 + 9 rc.h | 1 + 10 var.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 11 4 files changed, 99 insertions(+), 8 deletions(-) 12 13 diff --git a/exec.c b/exec.c 14 index ce9872a..987960d 100644 15 --- a/exec.c 16 +++ b/exec.c 17 @@ -265,6 +265,7 @@ main(int argc, char *argv[]) 18 Trapinit(); 19 Vinit(); 20 inttoascii(num, mypid = getpid()); 21 + pathinit(); 22 setvar("pid", newword(num, (word *)0)); 23 setvar("cflag", flag['c']?newword(flag['c'][0], (word *)0) 24 :(word *)0); 25 @@ -758,16 +759,15 @@ void 26 Xassign(void) 27 { 28 var *v; 29 + word *w; 30 31 - if(count(runq->argv->words)!=1){ 32 + w = Poplist(); 33 + if(count(w)!=1){ 34 Xerror1("= variable name not singleton!"); 35 return; 36 } 37 - v = vlook(runq->argv->words->word); 38 - poplist(); 39 - freewords(v->val); 40 - v->val = Poplist(); 41 - v->changed = 1; 42 + setvar(w->word, Poplist()); 43 + freewords(w); 44 } 45 46 /* 47 diff --git a/fns.h b/fns.h 48 index 1644d1e..a99f6fa 100644 49 --- a/fns.h 50 +++ b/fns.h 51 @@ -49,6 +49,7 @@ int mapfd(int); 52 int match(char*, char*, int); 53 char* makepath(char*, char*); 54 void panic(char*, int); 55 +void pathinit(void); 56 void pfln(io*, char*, int); 57 void poplist(void); 58 void popword(void); 59 diff --git a/rc.h b/rc.h 60 index a688663..3f48cce 100644 61 --- a/rc.h 62 +++ b/rc.h 63 @@ -117,6 +117,7 @@ struct var{ 64 int pc; /* pc of start of function */ 65 char fnchanged; 66 char changed; 67 + void (*changefn)(var*); 68 char name[]; 69 }; 70 var *vlook(char*), *gvlook(char*), *newvar(char*, var*); 71 diff --git a/var.c b/var.c 72 index 73b01fa..e132a7b 100644 73 --- a/var.c 74 +++ b/var.c 75 @@ -70,6 +70,7 @@ newvar(char *name, var *next) 76 v->fn = 0; 77 v->changed = 0; 78 v->fnchanged = 0; 79 + v->changefn = 0; 80 return v; 81 } 82 83 @@ -92,13 +93,21 @@ vlook(char *name) 84 return gvlook(name); 85 } 86 87 -void 88 -setvar(char *name, word *val) 89 +static void 90 +setvar_(char *name, word *val, int callfn) 91 { 92 var *v = vlook(name); 93 freewords(v->val); 94 v->val = val; 95 v->changed = 1; 96 + if(callfn && v->changefn) 97 + v->changefn(v); 98 +} 99 + 100 +void 101 +setvar(char *name, word *val) 102 +{ 103 + setvar_(name, val, 1); 104 } 105 106 void 107 @@ -107,3 +116,83 @@ freevar(var *v) 108 freewords(v->val); 109 free(v); 110 } 111 + 112 +static void 113 +bigpath(var *v) 114 +{ 115 + /* convert $PATH to $path */ 116 + char *p, *q; 117 + word **l, *w; 118 + 119 + if(v->val == 0){ 120 + setvar_("path", 0, 0); 121 + return; 122 + } 123 + p = v->val->word; 124 + w = 0; 125 + l = &w; 126 + /* 127 + * Doesn't handle escaped colon nonsense. 128 + */ 129 + if(p[0] == 0) 130 + p = 0; 131 + while(p){ 132 + q = strchr(p, ':'); 133 + if(q) 134 + *q = 0; 135 + *l = newword(p[0] ? p : ".", 0); 136 + l = &(*l)->next; 137 + if(q){ 138 + *q = ':'; 139 + p = q+1; 140 + }else 141 + p = 0; 142 + } 143 + setvar_("path", w, 0); 144 +} 145 + 146 +static char * 147 +list2strcolon(word *words) 148 +{ 149 + char *value, *s, *t; 150 + int len = 0; 151 + word *ap; 152 + for(ap = words;ap;ap = ap->next) 153 + len+=1+strlen(ap->word); 154 + value = emalloc(len+1); 155 + s = value; 156 + for(ap = words;ap;ap = ap->next){ 157 + for(t = ap->word;*t;) *s++=*t++; 158 + *s++=':'; 159 + } 160 + if(s==value) 161 + *s='\0'; 162 + else s[-1]='\0'; 163 + return value; 164 +} 165 + 166 +static void 167 +littlepath(var *v) 168 +{ 169 + /* convert $path to $PATH */ 170 + char *p; 171 + word *w; 172 + 173 + p = list2strcolon(v->val); 174 + w = new(word); 175 + w->word = p; 176 + w->next = 0; 177 + setvar_("PATH", w, 1); /* 1: recompute $path to expose colon problems */ 178 +} 179 + 180 +void 181 +pathinit(void) 182 +{ 183 + var *v; 184 + 185 + v = gvlook("path"); 186 + v->changefn = littlepath; 187 + v = gvlook("PATH"); 188 + v->changefn = bigpath; 189 + bigpath(v); 190 +} 191 -- 192 2.49.0 193