aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/rc
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-01-12 16:59:50 +0000
committerrsc <devnull@localhost>2005-01-12 16:59:50 +0000
commita9eaaa03e043ba8e1b2f67d7c8c7ba471db6ba4b (patch)
tree8bf6f1d90736df59a47098a94ea06a0501f99a76 /src/cmd/rc
parent7b0c2f155dc4ac20d65c6a9899ae223053379fcd (diff)
downloadplan9port-a9eaaa03e043ba8e1b2f67d7c8c7ba471db6ba4b.tar.gz
plan9port-a9eaaa03e043ba8e1b2f67d7c8c7ba471db6ba4b.tar.bz2
plan9port-a9eaaa03e043ba8e1b2f67d7c8c7ba471db6ba4b.zip
maintain $path and $PATH simultaneously
Diffstat (limited to 'src/cmd/rc')
-rw-r--r--src/cmd/rc/exec.c10
-rw-r--r--src/cmd/rc/fns.h3
-rw-r--r--src/cmd/rc/rc.h1
-rw-r--r--src/cmd/rc/simple.c2
-rw-r--r--src/cmd/rc/var.c62
5 files changed, 74 insertions, 4 deletions
diff --git a/src/cmd/rc/exec.c b/src/cmd/rc/exec.c
index ebed11d8..9ab7c29d 100644
--- a/src/cmd/rc/exec.c
+++ b/src/cmd/rc/exec.c
@@ -117,6 +117,7 @@ main(int argc, char *argv[])
Trapinit();
Vinit();
itoa(num, mypid=getpid());
+ pathinit();
setvar("pid", newword(num, (word *)0));
setvar("cflag", flag['c']?newword(flag['c'][0], (word *)0)
:(word *)0);
@@ -369,7 +370,7 @@ void Xwrite(void){
runq->pc++;
poplist();
}
-char *list2str(word *words){
+char *_list2str(word *words, int c){
char *value, *s, *t;
int len=0;
word *ap;
@@ -379,12 +380,15 @@ char *list2str(word *words){
s=value;
for(ap=words;ap;ap=ap->next){
for(t=ap->word;*t;) *s++=*t++;
- *s++=' ';
+ *s++=c;
}
if(s==value) *s='\0';
else s[-1]='\0';
return value;
}
+char *list2str(word *words){
+ return _list2str(words, ' ');
+}
void Xmatch(void){
word *p;
char *subject;
@@ -464,6 +468,8 @@ void Xassign(void){
freewords(v->val);
v->val=runq->argv->words;
v->changed=1;
+ if(v->changefn)
+ v->changefn(v);
runq->argv->words=0;
poplist();
}
diff --git a/src/cmd/rc/fns.h b/src/cmd/rc/fns.h
index 4c8be104..b9e5cb73 100644
--- a/src/cmd/rc/fns.h
+++ b/src/cmd/rc/fns.h
@@ -27,6 +27,7 @@ void cleanhere(char*);
void codefree(code*);
int compile(tree*);
char * list2str(word*);
+char * _list2str(word*, int);
int count(word*);
void deglob(char*);
void dotrap(void);
@@ -39,6 +40,7 @@ void kinit(void);
int match(char*, char*, int);
int matchfn(char*, char*);
void panic(char*, int);
+void pathinit(void);
void poplist(void);
void popword(void);
void pprompt(void);
@@ -48,6 +50,7 @@ void pushword(char*);
void readhere(void);
void setstatus(char*);
void setvar(char*, word*);
+void _setvar(char*, word*, int);
void skipnl(void);
void start(code*, int, var*);
int truestatus(void);
diff --git a/src/cmd/rc/rc.h b/src/cmd/rc/rc.h
index 9a739272..b7edbac4 100644
--- a/src/cmd/rc/rc.h
+++ b/src/cmd/rc/rc.h
@@ -84,6 +84,7 @@ struct var{
int fnchanged;
int pc; /* pc of start of function */
var *next; /* next on hash or local list */
+ void (*changefn)(var*);
};
var *vlook(char*), *gvlook(char*), *newvar(char*, var*);
#define NVAR 521
diff --git a/src/cmd/rc/simple.c b/src/cmd/rc/simple.c
index 5318c9fd..a65bec22 100644
--- a/src/cmd/rc/simple.c
+++ b/src/cmd/rc/simple.c
@@ -168,7 +168,7 @@ void execcd(void){
if(cdpath==0) pfmt(err, "Can't cd %s: %r\n", a->next->word);
break;
case 1:
- a=vlook("home")->val;
+ a=vlook("HOME")->val;
if(count(a)>=1){
if(dochdir(a->word)>=0)
setstatus("");
diff --git a/src/cmd/rc/var.c b/src/cmd/rc/var.c
index 73e4e9ae..8a200ffd 100644
--- a/src/cmd/rc/var.c
+++ b/src/cmd/rc/var.c
@@ -62,10 +62,70 @@ var *vlook(char *name)
if(strcmp(v->name, name)==0) return v;
return gvlook(name);
}
-void setvar(char *name, word *val)
+void _setvar(char *name, word *val, int callfn)
{
register struct 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 bigpath(var *v)
+{
+ /* convert $PATH to $path */
+ char *p, *q;
+ word **l, *w;
+
+ if(v->val == nil){
+ _setvar("path", nil, 0);
+ return;
+ }
+ p = v->val->word;
+ w = nil;
+ l = &w;
+ /*
+ * Doesn't handle escaped colon nonsense.
+ */
+ if(p[0] == 0)
+ p = nil;
+ while(p){
+ q = strchr(p, ':');
+ if(q)
+ *q = 0;
+ *l = newword(p[0] ? p : ".", nil);
+ l = &(*l)->next;
+ if(q){
+ *q = ':';
+ p = q+1;
+ }else
+ p = nil;
+ }
+ _setvar("path", w, 0);
+}
+void littlepath(var *v)
+{
+ /* convert $path to $PATH */
+ char *p;
+ word *w;
+
+ p = _list2str(v->val, ':');
+ w = new(word);
+ w->word = p;
+ w->next = nil;
+ _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);
}