opkg

statically linked package installer
git clone anongit@rnpnr.xyz:opkg.git
Log | Files | Refs | Feed | Submodules | README | LICENSE

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