1 f08fdedc 2003-11-23 devnull #include "rc.h"
2 f08fdedc 2003-11-23 devnull #include "getflags.h"
3 f08fdedc 2003-11-23 devnull #include "exec.h"
4 f08fdedc 2003-11-23 devnull #include "io.h"
5 f08fdedc 2003-11-23 devnull #include "fns.h"
7 f08fdedc 2003-11-23 devnull * Start executing the given code at the given pc with the given redirection
9 f08fdedc 2003-11-23 devnull char *argv0="rc";
12 c8f53842 2007-03-26 devnull start(code *c, int pc, var *local)
14 c8f53842 2007-03-26 devnull struct thread *p = new(struct thread);
16 c8f53842 2007-03-26 devnull p->code = codecopy(c);
17 c8f53842 2007-03-26 devnull p->pc = pc;
18 c8f53842 2007-03-26 devnull p->argv = 0;
19 c8f53842 2007-03-26 devnull p->redir = p->startredir = runq?runq->redir:0;
20 c8f53842 2007-03-26 devnull p->local = local;
21 c8f53842 2007-03-26 devnull p->cmdfile = 0;
22 c8f53842 2007-03-26 devnull p->cmdfd = 0;
23 c8f53842 2007-03-26 devnull p->eof = 0;
24 c8f53842 2007-03-26 devnull p->iflag = 0;
25 c8f53842 2007-03-26 devnull p->lineno = 1;
26 c8f53842 2007-03-26 devnull p->ret = runq;
27 c8f53842 2007-03-26 devnull runq = p;
31 c8f53842 2007-03-26 devnull newword(char *wd, word *next)
33 c8f53842 2007-03-26 devnull word *p = new(word);
34 c8f53842 2007-03-26 devnull p->word = strdup(wd);
35 c8f53842 2007-03-26 devnull p->next = next;
36 f08fdedc 2003-11-23 devnull return p;
40 c8f53842 2007-03-26 devnull pushword(char *wd)
42 c8f53842 2007-03-26 devnull if(runq->argv==0)
43 c8f53842 2007-03-26 devnull panic("pushword but no argv!", 0);
44 c8f53842 2007-03-26 devnull runq->argv->words = newword(wd, runq->argv->words);
48 c8f53842 2007-03-26 devnull popword(void)
51 c8f53842 2007-03-26 devnull if(runq->argv==0)
52 c8f53842 2007-03-26 devnull panic("popword but no argv!", 0);
53 c8f53842 2007-03-26 devnull p = runq->argv->words;
55 c8f53842 2007-03-26 devnull panic("popword but no word!", 0);
56 c8f53842 2007-03-26 devnull runq->argv->words = p->next;
57 f08fdedc 2003-11-23 devnull efree(p->word);
58 f08fdedc 2003-11-23 devnull efree((char *)p);
62 c8f53842 2007-03-26 devnull freelist(word *w)
64 f08fdedc 2003-11-23 devnull word *nw;
65 f08fdedc 2003-11-23 devnull while(w){
66 c8f53842 2007-03-26 devnull nw = w->next;
67 f08fdedc 2003-11-23 devnull efree(w->word);
68 f08fdedc 2003-11-23 devnull efree((char *)w);
74 c8f53842 2007-03-26 devnull pushlist(void)
76 c8f53842 2007-03-26 devnull list *p = new(list);
77 c8f53842 2007-03-26 devnull p->next = runq->argv;
78 c8f53842 2007-03-26 devnull p->words = 0;
79 c8f53842 2007-03-26 devnull runq->argv = p;
83 c8f53842 2007-03-26 devnull poplist(void)
85 c8f53842 2007-03-26 devnull list *p = runq->argv;
87 c8f53842 2007-03-26 devnull panic("poplist but no argv", 0);
88 f08fdedc 2003-11-23 devnull freelist(p->words);
89 c8f53842 2007-03-26 devnull runq->argv = p->next;
90 f08fdedc 2003-11-23 devnull efree((char *)p);
94 c8f53842 2007-03-26 devnull count(word *w)
97 c8f53842 2007-03-26 devnull for(n = 0;w;n++) w = w->next;
98 f08fdedc 2003-11-23 devnull return n;
102 c8f53842 2007-03-26 devnull pushredir(int type, int from, int to)
104 c8f53842 2007-03-26 devnull redir * rp = new(redir);
105 c8f53842 2007-03-26 devnull rp->type = type;
106 c8f53842 2007-03-26 devnull rp->from = from;
107 c8f53842 2007-03-26 devnull rp->to = to;
108 c8f53842 2007-03-26 devnull rp->next = runq->redir;
109 c8f53842 2007-03-26 devnull runq->redir = rp;
113 c8f53842 2007-03-26 devnull newvar(char *name, var *next)
115 c8f53842 2007-03-26 devnull var *v = new(var);
116 c8f53842 2007-03-26 devnull v->name = name;
117 c8f53842 2007-03-26 devnull v->val = 0;
118 c8f53842 2007-03-26 devnull v->fn = 0;
119 c8f53842 2007-03-26 devnull v->changed = 0;
120 c8f53842 2007-03-26 devnull v->fnchanged = 0;
121 c8f53842 2007-03-26 devnull v->next = next;
122 bd1b0cc1 2007-03-26 devnull v->changefn = 0;
123 f08fdedc 2003-11-23 devnull return v;
126 f08fdedc 2003-11-23 devnull * get command line flags, initialize keywords & traps.
127 f08fdedc 2003-11-23 devnull * get values from environment.
128 f08fdedc 2003-11-23 devnull * set $pid, $cflag, $*
129 f08fdedc 2003-11-23 devnull * fabricate bootstrap code and start it (*=(argv);. /usr/lib/rcmain $*)
130 f08fdedc 2003-11-23 devnull * start interpreting code
133 f08fdedc 2003-11-23 devnull main(int argc, char *argv[])
135 f08fdedc 2003-11-23 devnull code bootstrap[32];
136 f08fdedc 2003-11-23 devnull char num[12], *rcmain;
139 e3ffbf3b 2005-05-19 devnull /* needed for rcmain later */
140 0e4068e8 2005-07-26 devnull putenv("PLAN9", unsharp("#9"));
142 47d4646e 2020-05-05 rsc argc = getflags(argc, argv, "DSYsrdiIlxepvVc:1m:1[command]", 1);
143 c8f53842 2007-03-26 devnull if(argc==-1)
144 c8f53842 2007-03-26 devnull usage("[file [arg ...]]");
145 c8f53842 2007-03-26 devnull if(argv[0][0]=='-')
146 c8f53842 2007-03-26 devnull flag['l'] = flagset;
147 c8f53842 2007-03-26 devnull if(flag['I'])
148 c8f53842 2007-03-26 devnull flag['i'] = 0;
149 f08fdedc 2003-11-23 devnull else if(flag['i']==0 && argc==1 && Isatty(0)) flag['i'] = flagset;
150 c8f53842 2007-03-26 devnull rcmain = flag['m'] ? flag['m'][0] : Rcmain();
151 c8f53842 2007-03-26 devnull err = openfd(2);
152 f08fdedc 2003-11-23 devnull kinit();
153 f08fdedc 2003-11-23 devnull Trapinit();
154 f08fdedc 2003-11-23 devnull Vinit();
155 c8f53842 2007-03-26 devnull inttoascii(num, mypid = getpid());
156 a9eaaa03 2005-01-12 devnull pathinit();
157 f08fdedc 2003-11-23 devnull setvar("pid", newword(num, (word *)0));
158 f08fdedc 2003-11-23 devnull setvar("cflag", flag['c']?newword(flag['c'][0], (word *)0)
159 f08fdedc 2003-11-23 devnull :(word *)0);
160 f08fdedc 2003-11-23 devnull setvar("rcname", newword(argv[0], (word *)0));
162 c8f53842 2007-03-26 devnull bootstrap[i++].i = 1;
163 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xmark;
164 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xword;
165 f08fdedc 2003-11-23 devnull bootstrap[i++].s="*";
166 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xassign;
167 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xmark;
168 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xmark;
169 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xword;
170 f08fdedc 2003-11-23 devnull bootstrap[i++].s="*";
171 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xdol;
172 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xword;
173 c8f53842 2007-03-26 devnull bootstrap[i++].s = rcmain;
174 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xword;
175 f08fdedc 2003-11-23 devnull bootstrap[i++].s=".";
176 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xsimple;
177 c8f53842 2007-03-26 devnull bootstrap[i++].f = Xexit;
178 c8f53842 2007-03-26 devnull bootstrap[i].i = 0;
179 f08fdedc 2003-11-23 devnull start(bootstrap, 1, (var *)0);
180 f08fdedc 2003-11-23 devnull /* prime bootstrap argv */
181 f08fdedc 2003-11-23 devnull pushlist();
182 f08fdedc 2003-11-23 devnull argv0 = strdup(argv[0]);
183 c8f53842 2007-03-26 devnull for(i = argc-1;i!=0;--i) pushword(argv[i]);
184 f08fdedc 2003-11-23 devnull for(;;){
185 c8f53842 2007-03-26 devnull if(flag['r'])
186 c8f53842 2007-03-26 devnull pfnc(err, runq);
187 f08fdedc 2003-11-23 devnull runq->pc++;
188 f08fdedc 2003-11-23 devnull (*runq->code[runq->pc-1].f)();
189 c8f53842 2007-03-26 devnull if(ntrap)
190 c8f53842 2007-03-26 devnull dotrap();
192 a3b799d9 2011-08-02 rsc return 0; /* not reached; silence OS X Lion gcc */
195 f08fdedc 2003-11-23 devnull * Opcode routines
196 f08fdedc 2003-11-23 devnull * Arguments on stack (...)
197 f08fdedc 2003-11-23 devnull * Arguments in line [...]
198 f08fdedc 2003-11-23 devnull * Code in line with jump around {...}
200 f08fdedc 2003-11-23 devnull * Xappend(file)[fd] open file to append
201 f08fdedc 2003-11-23 devnull * Xassign(name, val) assign val to name
202 f08fdedc 2003-11-23 devnull * Xasync{... Xexit} make thread for {}, no wait
203 f08fdedc 2003-11-23 devnull * Xbackq{... Xreturn} make thread for {}, push stdout
204 f08fdedc 2003-11-23 devnull * Xbang complement condition
205 f08fdedc 2003-11-23 devnull * Xcase(pat, value){...} exec code on match, leave (value) on
207 f08fdedc 2003-11-23 devnull * Xclose[i] close file descriptor
208 f08fdedc 2003-11-23 devnull * Xconc(left, right) concatenate, push results
209 f08fdedc 2003-11-23 devnull * Xcount(name) push var count
210 f08fdedc 2003-11-23 devnull * Xdelfn(name) delete function definition
211 f08fdedc 2003-11-23 devnull * Xdeltraps(names) delete named traps
212 f08fdedc 2003-11-23 devnull * Xdol(name) get variable value
213 f08fdedc 2003-11-23 devnull * Xqdol(name) concatenate variable components
214 f08fdedc 2003-11-23 devnull * Xdup[i j] dup file descriptor
215 f08fdedc 2003-11-23 devnull * Xexit rc exits with status
216 f08fdedc 2003-11-23 devnull * Xfalse{...} execute {} if false
217 f08fdedc 2003-11-23 devnull * Xfn(name){... Xreturn} define function
218 f08fdedc 2003-11-23 devnull * Xfor(var, list){... Xreturn} for loop
219 f08fdedc 2003-11-23 devnull * Xjump[addr] goto
220 f08fdedc 2003-11-23 devnull * Xlocal(name, val) create local variable, assign value
221 f08fdedc 2003-11-23 devnull * Xmark mark stack
222 f08fdedc 2003-11-23 devnull * Xmatch(pat, str) match pattern, set status
223 f08fdedc 2003-11-23 devnull * Xpipe[i j]{... Xreturn}{... Xreturn} construct a pipe between 2 new threads,
224 f08fdedc 2003-11-23 devnull * wait for both
225 f08fdedc 2003-11-23 devnull * Xpipefd[type]{... Xreturn} connect {} to pipe (input or output,
226 f08fdedc 2003-11-23 devnull * depending on type), push /dev/fd/??
227 f08fdedc 2003-11-23 devnull * Xpopm(value) pop value from stack
228 c8f53842 2007-03-26 devnull * Xrdwr(file)[fd] open file for reading and writing
229 f08fdedc 2003-11-23 devnull * Xread(file)[fd] open file to read
230 f08fdedc 2003-11-23 devnull * Xsettraps(names){... Xreturn} define trap functions
231 f08fdedc 2003-11-23 devnull * Xshowtraps print trap list
232 f08fdedc 2003-11-23 devnull * Xsimple(args) run command and wait
233 f08fdedc 2003-11-23 devnull * Xreturn kill thread
234 f08fdedc 2003-11-23 devnull * Xsubshell{... Xexit} execute {} in a subshell and wait
235 f08fdedc 2003-11-23 devnull * Xtrue{...} execute {} if true
236 f08fdedc 2003-11-23 devnull * Xunlocal delete local variable
237 f08fdedc 2003-11-23 devnull * Xword[string] push string
238 f08fdedc 2003-11-23 devnull * Xwrite(file)[fd] open file to write
242 c8f53842 2007-03-26 devnull Xappend(void)
244 f08fdedc 2003-11-23 devnull char *file;
246 f08fdedc 2003-11-23 devnull switch(count(runq->argv->words)){
247 c8f53842 2007-03-26 devnull default:
248 c8f53842 2007-03-26 devnull Xerror1(">> requires singleton");
251 c8f53842 2007-03-26 devnull Xerror1(">> requires file");
256 c8f53842 2007-03-26 devnull file = runq->argv->words->word;
257 c8f53842 2007-03-26 devnull if((f = open(file, 1))<0 && (f = Creat(file))<0){
258 f08fdedc 2003-11-23 devnull pfmt(err, "%s: ", file);
259 f08fdedc 2003-11-23 devnull Xerror("can't open");
262 f08fdedc 2003-11-23 devnull Seek(f, 0L, 2);
263 f08fdedc 2003-11-23 devnull pushredir(ROPEN, f, runq->code[runq->pc].i);
264 f08fdedc 2003-11-23 devnull runq->pc++;
265 f08fdedc 2003-11-23 devnull poplist();
269 c8f53842 2007-03-26 devnull Xsettrue(void)
271 f08fdedc 2003-11-23 devnull setstatus("");
275 c8f53842 2007-03-26 devnull Xbang(void)
277 f08fdedc 2003-11-23 devnull setstatus(truestatus()?"false":"");
281 c8f53842 2007-03-26 devnull Xclose(void)
283 f08fdedc 2003-11-23 devnull pushredir(RCLOSE, runq->code[runq->pc].i, 0);
284 f08fdedc 2003-11-23 devnull runq->pc++;
288 c8f53842 2007-03-26 devnull Xdup(void)
290 f08fdedc 2003-11-23 devnull pushredir(RDUP, runq->code[runq->pc].i, runq->code[runq->pc+1].i);
291 f08fdedc 2003-11-23 devnull runq->pc+=2;
295 c8f53842 2007-03-26 devnull Xeflag(void)
297 f08fdedc 2003-11-23 devnull if(eflagok && !truestatus()) Xexit();
301 c8f53842 2007-03-26 devnull Xexit(void)
303 f08fdedc 2003-11-23 devnull struct var *trapreq;
304 f08fdedc 2003-11-23 devnull struct word *starval;
305 c8f53842 2007-03-26 devnull static int beenhere = 0;
306 f08fdedc 2003-11-23 devnull if(getpid()==mypid && !beenhere){
307 c8f53842 2007-03-26 devnull trapreq = vlook("sigexit");
308 f08fdedc 2003-11-23 devnull if(trapreq->fn){
309 c8f53842 2007-03-26 devnull beenhere = 1;
310 f08fdedc 2003-11-23 devnull --runq->pc;
311 c8f53842 2007-03-26 devnull starval = vlook("*")->val;
312 f08fdedc 2003-11-23 devnull start(trapreq->fn, trapreq->pc, (struct var *)0);
313 c8f53842 2007-03-26 devnull runq->local = newvar(strdup("*"), runq->local);
314 c8f53842 2007-03-26 devnull runq->local->val = copywords(starval, (struct word *)0);
315 c8f53842 2007-03-26 devnull runq->local->changed = 1;
316 c8f53842 2007-03-26 devnull runq->redir = runq->startredir = 0;
320 f08fdedc 2003-11-23 devnull Exit(getstatus());
324 c8f53842 2007-03-26 devnull Xfalse(void)
326 c8f53842 2007-03-26 devnull if(truestatus()) runq->pc = runq->code[runq->pc].i;
327 f08fdedc 2003-11-23 devnull else runq->pc++;
329 f08fdedc 2003-11-23 devnull int ifnot; /* dynamic if not flag */
332 c8f53842 2007-03-26 devnull Xifnot(void)
334 f08fdedc 2003-11-23 devnull if(ifnot)
335 f08fdedc 2003-11-23 devnull runq->pc++;
337 c8f53842 2007-03-26 devnull runq->pc = runq->code[runq->pc].i;
341 c8f53842 2007-03-26 devnull Xjump(void)
343 c8f53842 2007-03-26 devnull runq->pc = runq->code[runq->pc].i;
347 c8f53842 2007-03-26 devnull Xmark(void)
349 f08fdedc 2003-11-23 devnull pushlist();
353 c8f53842 2007-03-26 devnull Xpopm(void)
355 f08fdedc 2003-11-23 devnull poplist();
359 c8f53842 2007-03-26 devnull Xread(void)
361 f08fdedc 2003-11-23 devnull char *file;
363 f08fdedc 2003-11-23 devnull switch(count(runq->argv->words)){
364 c8f53842 2007-03-26 devnull default:
365 c8f53842 2007-03-26 devnull Xerror1("< requires singleton\n");
368 c8f53842 2007-03-26 devnull Xerror1("< requires file\n");
373 c8f53842 2007-03-26 devnull file = runq->argv->words->word;
374 c8f53842 2007-03-26 devnull if((f = open(file, 0))<0){
375 f08fdedc 2003-11-23 devnull pfmt(err, "%s: ", file);
376 f08fdedc 2003-11-23 devnull Xerror("can't open");
379 f08fdedc 2003-11-23 devnull pushredir(ROPEN, f, runq->code[runq->pc].i);
380 f08fdedc 2003-11-23 devnull runq->pc++;
381 f08fdedc 2003-11-23 devnull poplist();
385 c8f53842 2007-03-26 devnull Xrdwr(void)
387 c8f53842 2007-03-26 devnull char *file;
390 c8f53842 2007-03-26 devnull switch(count(runq->argv->words)){
391 c8f53842 2007-03-26 devnull default:
392 c8f53842 2007-03-26 devnull Xerror1("<> requires singleton\n");
395 c8f53842 2007-03-26 devnull Xerror1("<> requires file\n");
400 c8f53842 2007-03-26 devnull file = runq->argv->words->word;
401 c8f53842 2007-03-26 devnull if((f = open(file, ORDWR))<0){
402 c8f53842 2007-03-26 devnull pfmt(err, "%s: ", file);
403 c8f53842 2007-03-26 devnull Xerror("can't open");
406 c8f53842 2007-03-26 devnull pushredir(ROPEN, f, runq->code[runq->pc].i);
407 c8f53842 2007-03-26 devnull runq->pc++;
408 c8f53842 2007-03-26 devnull poplist();
412 c8f53842 2007-03-26 devnull turfredir(void)
414 f08fdedc 2003-11-23 devnull while(runq->redir!=runq->startredir)
415 f08fdedc 2003-11-23 devnull Xpopredir();
419 c8f53842 2007-03-26 devnull Xpopredir(void)
421 c8f53842 2007-03-26 devnull struct redir *rp = runq->redir;
422 c8f53842 2007-03-26 devnull if(rp==0)
423 c8f53842 2007-03-26 devnull panic("turfredir null!", 0);
424 c8f53842 2007-03-26 devnull runq->redir = rp->next;
425 c8f53842 2007-03-26 devnull if(rp->type==ROPEN)
426 c8f53842 2007-03-26 devnull close(rp->from);
427 f08fdedc 2003-11-23 devnull efree((char *)rp);
431 c8f53842 2007-03-26 devnull Xreturn(void)
433 c8f53842 2007-03-26 devnull struct thread *p = runq;
434 f08fdedc 2003-11-23 devnull turfredir();
435 f08fdedc 2003-11-23 devnull while(p->argv) poplist();
436 f08fdedc 2003-11-23 devnull codefree(p->code);
437 c8f53842 2007-03-26 devnull runq = p->ret;
438 f08fdedc 2003-11-23 devnull efree((char *)p);
439 c8f53842 2007-03-26 devnull if(runq==0)
440 c8f53842 2007-03-26 devnull Exit(getstatus());
444 c8f53842 2007-03-26 devnull Xtrue(void)
446 f08fdedc 2003-11-23 devnull if(truestatus()) runq->pc++;
447 c8f53842 2007-03-26 devnull else runq->pc = runq->code[runq->pc].i;
451 c8f53842 2007-03-26 devnull Xif(void)
453 c8f53842 2007-03-26 devnull ifnot = 1;
454 f08fdedc 2003-11-23 devnull if(truestatus()) runq->pc++;
455 c8f53842 2007-03-26 devnull else runq->pc = runq->code[runq->pc].i;
459 c8f53842 2007-03-26 devnull Xwastrue(void)
461 c8f53842 2007-03-26 devnull ifnot = 0;
465 c8f53842 2007-03-26 devnull Xword(void)
467 f08fdedc 2003-11-23 devnull pushword(runq->code[runq->pc++].s);
471 c8f53842 2007-03-26 devnull Xwrite(void)
473 f08fdedc 2003-11-23 devnull char *file;
475 f08fdedc 2003-11-23 devnull switch(count(runq->argv->words)){
476 c8f53842 2007-03-26 devnull default:
477 c8f53842 2007-03-26 devnull Xerror1("> requires singleton\n");
480 c8f53842 2007-03-26 devnull Xerror1("> requires file\n");
485 c8f53842 2007-03-26 devnull file = runq->argv->words->word;
486 c8f53842 2007-03-26 devnull if((f = Creat(file))<0){
487 f08fdedc 2003-11-23 devnull pfmt(err, "%s: ", file);
488 f08fdedc 2003-11-23 devnull Xerror("can't open");
491 f08fdedc 2003-11-23 devnull pushredir(ROPEN, f, runq->code[runq->pc].i);
492 f08fdedc 2003-11-23 devnull runq->pc++;
493 f08fdedc 2003-11-23 devnull poplist();
497 c8f53842 2007-03-26 devnull list2str(word *words)
499 f08fdedc 2003-11-23 devnull char *value, *s, *t;
500 c8f53842 2007-03-26 devnull int len = 0;
501 f08fdedc 2003-11-23 devnull word *ap;
502 c8f53842 2007-03-26 devnull for(ap = words;ap;ap = ap->next)
503 f08fdedc 2003-11-23 devnull len+=1+strlen(ap->word);
504 c8f53842 2007-03-26 devnull value = emalloc(len+1);
505 c8f53842 2007-03-26 devnull s = value;
506 c8f53842 2007-03-26 devnull for(ap = words;ap;ap = ap->next){
507 c8f53842 2007-03-26 devnull for(t = ap->word;*t;) *s++=*t++;
508 c8f53842 2007-03-26 devnull *s++=' ';
510 c8f53842 2007-03-26 devnull if(s==value)
511 c8f53842 2007-03-26 devnull *s='\0';
512 f08fdedc 2003-11-23 devnull else s[-1]='\0';
513 f08fdedc 2003-11-23 devnull return value;
517 c8f53842 2007-03-26 devnull Xmatch(void)
519 f08fdedc 2003-11-23 devnull word *p;
520 f08fdedc 2003-11-23 devnull char *subject;
521 c8f53842 2007-03-26 devnull subject = list2str(runq->argv->words);
522 f08fdedc 2003-11-23 devnull setstatus("no match");
523 c8f53842 2007-03-26 devnull for(p = runq->argv->next->words;p;p = p->next)
524 f08fdedc 2003-11-23 devnull if(match(subject, p->word, '\0')){
525 f08fdedc 2003-11-23 devnull setstatus("");
528 f08fdedc 2003-11-23 devnull efree(subject);
529 f08fdedc 2003-11-23 devnull poplist();
530 f08fdedc 2003-11-23 devnull poplist();
534 c8f53842 2007-03-26 devnull Xcase(void)
536 f08fdedc 2003-11-23 devnull word *p;
537 f08fdedc 2003-11-23 devnull char *s;
538 c8f53842 2007-03-26 devnull int ok = 0;
539 c8f53842 2007-03-26 devnull s = list2str(runq->argv->next->words);
540 c8f53842 2007-03-26 devnull for(p = runq->argv->words;p;p = p->next){
541 f08fdedc 2003-11-23 devnull if(match(s, p->word, '\0')){
546 f08fdedc 2003-11-23 devnull efree(s);
548 f08fdedc 2003-11-23 devnull runq->pc++;
550 c8f53842 2007-03-26 devnull runq->pc = runq->code[runq->pc].i;
551 f08fdedc 2003-11-23 devnull poplist();
555 c8f53842 2007-03-26 devnull conclist(word *lp, word *rp, word *tail)
557 f08fdedc 2003-11-23 devnull char *buf;
558 f08fdedc 2003-11-23 devnull word *v;
559 f08fdedc 2003-11-23 devnull if(lp->next || rp->next)
560 c8f53842 2007-03-26 devnull tail = conclist(lp->next==0?lp:lp->next, rp->next==0?rp:rp->next,
562 c8f53842 2007-03-26 devnull buf = emalloc(strlen(lp->word)+strlen(rp->word)+1);
563 f08fdedc 2003-11-23 devnull strcpy(buf, lp->word);
564 f08fdedc 2003-11-23 devnull strcat(buf, rp->word);
565 c8f53842 2007-03-26 devnull v = newword(buf, tail);
566 f08fdedc 2003-11-23 devnull efree(buf);
567 f08fdedc 2003-11-23 devnull return v;
571 c8f53842 2007-03-26 devnull Xconc(void)
573 c8f53842 2007-03-26 devnull word *lp = runq->argv->words;
574 c8f53842 2007-03-26 devnull word *rp = runq->argv->next->words;
575 c8f53842 2007-03-26 devnull word *vp = runq->argv->next->next->words;
576 c8f53842 2007-03-26 devnull int lc = count(lp), rc = count(rp);
577 f08fdedc 2003-11-23 devnull if(lc!=0 || rc!=0){
578 f08fdedc 2003-11-23 devnull if(lc==0 || rc==0){
579 f08fdedc 2003-11-23 devnull Xerror1("null list in concatenation");
582 f08fdedc 2003-11-23 devnull if(lc!=1 && rc!=1 && lc!=rc){
583 f08fdedc 2003-11-23 devnull Xerror1("mismatched list lengths in concatenation");
586 c8f53842 2007-03-26 devnull vp = conclist(lp, rp, vp);
588 f08fdedc 2003-11-23 devnull poplist();
589 f08fdedc 2003-11-23 devnull poplist();
590 c8f53842 2007-03-26 devnull runq->argv->words = vp;
594 c8f53842 2007-03-26 devnull Xassign(void)
597 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)!=1){
598 f08fdedc 2003-11-23 devnull Xerror1("variable name not singleton!");
601 f08fdedc 2003-11-23 devnull deglob(runq->argv->words->word);
602 c8f53842 2007-03-26 devnull v = vlook(runq->argv->words->word);
603 f08fdedc 2003-11-23 devnull poplist();
604 f08fdedc 2003-11-23 devnull globlist();
605 f08fdedc 2003-11-23 devnull freewords(v->val);
606 c8f53842 2007-03-26 devnull v->val = runq->argv->words;
607 c8f53842 2007-03-26 devnull v->changed = 1;
608 fbc629a9 2007-03-28 devnull if(v->changefn)
609 fbc629a9 2007-03-28 devnull v->changefn(v);
610 c8f53842 2007-03-26 devnull runq->argv->words = 0;
611 f08fdedc 2003-11-23 devnull poplist();
614 f08fdedc 2003-11-23 devnull * copy arglist a, adding the copy to the front of tail
618 c8f53842 2007-03-26 devnull copywords(word *a, word *tail)
620 c8f53842 2007-03-26 devnull word *v = 0, **end;
621 c8f53842 2007-03-26 devnull for(end=&v;a;a = a->next,end=&(*end)->next)
622 c8f53842 2007-03-26 devnull *end = newword(a->word, 0);
623 c8f53842 2007-03-26 devnull *end = tail;
624 f08fdedc 2003-11-23 devnull return v;
628 c8f53842 2007-03-26 devnull Xdol(void)
630 f08fdedc 2003-11-23 devnull word *a, *star;
631 f08fdedc 2003-11-23 devnull char *s, *t;
633 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)!=1){
634 f08fdedc 2003-11-23 devnull Xerror1("variable name not singleton!");
637 c8f53842 2007-03-26 devnull s = runq->argv->words->word;
638 f08fdedc 2003-11-23 devnull deglob(s);
640 c8f53842 2007-03-26 devnull for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0';
641 c8f53842 2007-03-26 devnull a = runq->argv->next->words;
642 f08fdedc 2003-11-23 devnull if(n==0 || *t)
643 c8f53842 2007-03-26 devnull a = copywords(vlook(s)->val, a);
645 c8f53842 2007-03-26 devnull star = vlook("*")->val;
646 f08fdedc 2003-11-23 devnull if(star && 1<=n && n<=count(star)){
647 c8f53842 2007-03-26 devnull while(--n) star = star->next;
648 c8f53842 2007-03-26 devnull a = newword(star->word, a);
651 f08fdedc 2003-11-23 devnull poplist();
652 c8f53842 2007-03-26 devnull runq->argv->words = a;
656 c8f53842 2007-03-26 devnull Xqdol(void)
658 f08fdedc 2003-11-23 devnull word *a, *p;
659 f08fdedc 2003-11-23 devnull char *s;
661 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)!=1){
662 f08fdedc 2003-11-23 devnull Xerror1("variable name not singleton!");
665 c8f53842 2007-03-26 devnull s = runq->argv->words->word;
666 f08fdedc 2003-11-23 devnull deglob(s);
667 c8f53842 2007-03-26 devnull a = vlook(s)->val;
668 f08fdedc 2003-11-23 devnull poplist();
669 c8f53842 2007-03-26 devnull n = count(a);
670 f08fdedc 2003-11-23 devnull if(n==0){
671 f08fdedc 2003-11-23 devnull pushword("");
674 c8f53842 2007-03-26 devnull for(p = a;p;p = p->next) n+=strlen(p->word);
675 c8f53842 2007-03-26 devnull s = emalloc(n);
677 f08fdedc 2003-11-23 devnull strcpy(s, a->word);
678 c8f53842 2007-03-26 devnull for(p = a->next;p;p = p->next){
679 f08fdedc 2003-11-23 devnull strcat(s, " ");
680 f08fdedc 2003-11-23 devnull strcat(s, p->word);
684 f08fdedc 2003-11-23 devnull s[0]='\0';
685 f08fdedc 2003-11-23 devnull pushword(s);
686 f08fdedc 2003-11-23 devnull efree(s);
690 94e1f2a4 2008-07-20 rsc copynwords(word *a, word *tail, int n)
692 94e1f2a4 2008-07-20 rsc word *v, **end;
696 94e1f2a4 2008-07-20 rsc while(n-- > 0){
697 94e1f2a4 2008-07-20 rsc *end = newword(a->word, 0);
698 94e1f2a4 2008-07-20 rsc end = &(*end)->next;
699 94e1f2a4 2008-07-20 rsc a = a->next;
701 94e1f2a4 2008-07-20 rsc *end = tail;
706 c8f53842 2007-03-26 devnull subwords(word *val, int len, word *sub, word *a)
709 f08fdedc 2003-11-23 devnull char *s;
710 c8f53842 2007-03-26 devnull if(!sub)
711 c8f53842 2007-03-26 devnull return a;
712 c8f53842 2007-03-26 devnull a = subwords(val, len, sub->next, a);
713 c8f53842 2007-03-26 devnull s = sub->word;
714 f08fdedc 2003-11-23 devnull deglob(s);
717 94e1f2a4 2008-07-20 rsc while('0'<=*s && *s<='9')
718 94e1f2a4 2008-07-20 rsc n = n*10+ *s++ -'0';
719 94e1f2a4 2008-07-20 rsc if(*s == '-'){
720 94e1f2a4 2008-07-20 rsc if(*++s == 0)
721 94e1f2a4 2008-07-20 rsc m = len - n;
723 94e1f2a4 2008-07-20 rsc while('0'<=*s && *s<='9')
724 94e1f2a4 2008-07-20 rsc m = m*10+ *s++ -'0';
728 94e1f2a4 2008-07-20 rsc if(n<1 || n>len || m<0)
729 c8f53842 2007-03-26 devnull return a;
732 94e1f2a4 2008-07-20 rsc while(--n > 0)
733 94e1f2a4 2008-07-20 rsc val = val->next;
734 94e1f2a4 2008-07-20 rsc return copynwords(val, a, m+1);
738 c8f53842 2007-03-26 devnull Xsub(void)
740 f08fdedc 2003-11-23 devnull word *a, *v;
741 f08fdedc 2003-11-23 devnull char *s;
742 f08fdedc 2003-11-23 devnull if(count(runq->argv->next->words)!=1){
743 f08fdedc 2003-11-23 devnull Xerror1("variable name not singleton!");
746 c8f53842 2007-03-26 devnull s = runq->argv->next->words->word;
747 f08fdedc 2003-11-23 devnull deglob(s);
748 c8f53842 2007-03-26 devnull a = runq->argv->next->next->words;
749 c8f53842 2007-03-26 devnull v = vlook(s)->val;
750 c8f53842 2007-03-26 devnull a = subwords(v, count(v), runq->argv->words, a);
751 f08fdedc 2003-11-23 devnull poplist();
752 f08fdedc 2003-11-23 devnull poplist();
753 c8f53842 2007-03-26 devnull runq->argv->words = a;
757 c8f53842 2007-03-26 devnull Xcount(void)
759 f08fdedc 2003-11-23 devnull word *a;
760 f08fdedc 2003-11-23 devnull char *s, *t;
762 f08fdedc 2003-11-23 devnull char num[12];
763 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)!=1){
764 f08fdedc 2003-11-23 devnull Xerror1("variable name not singleton!");
767 c8f53842 2007-03-26 devnull s = runq->argv->words->word;
768 f08fdedc 2003-11-23 devnull deglob(s);
770 c8f53842 2007-03-26 devnull for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0';
771 f08fdedc 2003-11-23 devnull if(n==0 || *t){
772 c8f53842 2007-03-26 devnull a = vlook(s)->val;
773 c8f53842 2007-03-26 devnull inttoascii(num, count(a));
776 c8f53842 2007-03-26 devnull a = vlook("*")->val;
777 c8f53842 2007-03-26 devnull inttoascii(num, a && 1<=n && n<=count(a)?1:0);
779 f08fdedc 2003-11-23 devnull poplist();
780 f08fdedc 2003-11-23 devnull pushword(num);
784 c8f53842 2007-03-26 devnull Xlocal(void)
786 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)!=1){
787 f08fdedc 2003-11-23 devnull Xerror1("variable name must be singleton\n");
790 f08fdedc 2003-11-23 devnull deglob(runq->argv->words->word);
791 c8f53842 2007-03-26 devnull runq->local = newvar(strdup(runq->argv->words->word), runq->local);
792 c8f53842 2007-03-26 devnull runq->local->val = copywords(runq->argv->next->words, (word *)0);
793 c8f53842 2007-03-26 devnull runq->local->changed = 1;
794 f08fdedc 2003-11-23 devnull poplist();
795 f08fdedc 2003-11-23 devnull poplist();
799 c8f53842 2007-03-26 devnull Xunlocal(void)
801 c8f53842 2007-03-26 devnull var *v = runq->local, *hid;
802 c8f53842 2007-03-26 devnull if(v==0)
803 c8f53842 2007-03-26 devnull panic("Xunlocal: no locals!", 0);
804 c8f53842 2007-03-26 devnull runq->local = v->next;
805 c8f53842 2007-03-26 devnull hid = vlook(v->name);
806 c8f53842 2007-03-26 devnull hid->changed = 1;
807 f08fdedc 2003-11-23 devnull efree(v->name);
808 f08fdedc 2003-11-23 devnull freewords(v->val);
809 f08fdedc 2003-11-23 devnull efree((char *)v);
813 c8f53842 2007-03-26 devnull freewords(word *w)
815 f08fdedc 2003-11-23 devnull word *nw;
816 f08fdedc 2003-11-23 devnull while(w){
817 f08fdedc 2003-11-23 devnull efree(w->word);
818 c8f53842 2007-03-26 devnull nw = w->next;
819 f08fdedc 2003-11-23 devnull efree((char *)w);
825 c8f53842 2007-03-26 devnull Xfn(void)
828 f08fdedc 2003-11-23 devnull word *a;
829 f08fdedc 2003-11-23 devnull int end;
830 c8f53842 2007-03-26 devnull end = runq->code[runq->pc].i;
831 c8f53842 2007-03-26 devnull for(a = runq->argv->words;a;a = a->next){
832 c8f53842 2007-03-26 devnull v = gvlook(a->word);
833 c8f53842 2007-03-26 devnull if(v->fn)
834 c8f53842 2007-03-26 devnull codefree(v->fn);
835 c8f53842 2007-03-26 devnull v->fn = codecopy(runq->code);
836 c8f53842 2007-03-26 devnull v->pc = runq->pc+2;
837 c8f53842 2007-03-26 devnull v->fnchanged = 1;
839 c8f53842 2007-03-26 devnull runq->pc = end;
840 f08fdedc 2003-11-23 devnull poplist();
844 c8f53842 2007-03-26 devnull Xdelfn(void)
847 f08fdedc 2003-11-23 devnull word *a;
848 c8f53842 2007-03-26 devnull for(a = runq->argv->words;a;a = a->next){
849 c8f53842 2007-03-26 devnull v = gvlook(a->word);
850 c8f53842 2007-03-26 devnull if(v->fn)
851 c8f53842 2007-03-26 devnull codefree(v->fn);
852 c8f53842 2007-03-26 devnull v->fn = 0;
853 c8f53842 2007-03-26 devnull v->fnchanged = 1;
855 f08fdedc 2003-11-23 devnull poplist();
859 c8f53842 2007-03-26 devnull concstatus(char *s, char *t)
861 f08fdedc 2003-11-23 devnull static char v[NSTATUS+1];
862 c8f53842 2007-03-26 devnull int n = strlen(s);
863 f08fdedc 2003-11-23 devnull strncpy(v, s, NSTATUS);
864 f08fdedc 2003-11-23 devnull if(n<NSTATUS){
865 f08fdedc 2003-11-23 devnull v[n]='|';
866 f08fdedc 2003-11-23 devnull strncpy(v+n+1, t, NSTATUS-n-1);
868 f08fdedc 2003-11-23 devnull v[NSTATUS]='\0';
869 f08fdedc 2003-11-23 devnull return v;
873 c8f53842 2007-03-26 devnull Xpipewait(void)
875 f08fdedc 2003-11-23 devnull char status[NSTATUS+1];
876 f08fdedc 2003-11-23 devnull if(runq->pid==-1)
877 f08fdedc 2003-11-23 devnull setstatus(concstatus(runq->status, getstatus()));
879 f08fdedc 2003-11-23 devnull strncpy(status, getstatus(), NSTATUS);
880 f08fdedc 2003-11-23 devnull status[NSTATUS]='\0';
881 f08fdedc 2003-11-23 devnull Waitfor(runq->pid, 1);
882 f08fdedc 2003-11-23 devnull runq->pid=-1;
883 f08fdedc 2003-11-23 devnull setstatus(concstatus(getstatus(), status));
888 c8f53842 2007-03-26 devnull Xrdcmds(void)
890 c8f53842 2007-03-26 devnull struct thread *p = runq;
891 f08fdedc 2003-11-23 devnull word *prompt;
892 f08fdedc 2003-11-23 devnull flush(err);
893 c8f53842 2007-03-26 devnull nerror = 0;
894 f08fdedc 2003-11-23 devnull if(flag['s'] && !truestatus())
895 f08fdedc 2003-11-23 devnull pfmt(err, "status=%v\n", vlook("status")->val);
896 f08fdedc 2003-11-23 devnull if(runq->iflag){
897 c8f53842 2007-03-26 devnull prompt = vlook("prompt")->val;
898 f08fdedc 2003-11-23 devnull if(prompt)
899 c8f53842 2007-03-26 devnull promptstr = prompt->word;
901 f08fdedc 2003-11-23 devnull promptstr="% ";
903 f08fdedc 2003-11-23 devnull Noerror();
904 47d4646e 2020-05-05 rsc if((flag['Y'] ? yyparse : parse)()){
905 f08fdedc 2003-11-23 devnull if(!p->iflag || p->eof && !Eintr()){
906 c8f53842 2007-03-26 devnull if(p->cmdfile)
907 c8f53842 2007-03-26 devnull efree(p->cmdfile);
908 f08fdedc 2003-11-23 devnull closeio(p->cmdfd);
909 f08fdedc 2003-11-23 devnull Xreturn(); /* should this be omitted? */
912 f08fdedc 2003-11-23 devnull if(Eintr()){
913 f08fdedc 2003-11-23 devnull pchr(err, '\n');
914 c8f53842 2007-03-26 devnull p->eof = 0;
916 f08fdedc 2003-11-23 devnull --p->pc; /* go back for next command */
920 f08fdedc 2003-11-23 devnull ntrap = 0; /* avoid double-interrupts during blocked writes */
921 f08fdedc 2003-11-23 devnull --p->pc; /* re-execute Xrdcmds after codebuf runs */
922 f08fdedc 2003-11-23 devnull start(codebuf, 1, runq->local);
924 f08fdedc 2003-11-23 devnull freenodes();
928 c8f53842 2007-03-26 devnull Xerror(char *s)
930 f08fdedc 2003-11-23 devnull if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0)
931 f08fdedc 2003-11-23 devnull pfmt(err, "rc: %s: %r\n", s);
933 f08fdedc 2003-11-23 devnull pfmt(err, "rc (%s): %s: %r\n", argv0, s);
934 f08fdedc 2003-11-23 devnull flush(err);
935 4ae2f414 2005-08-11 devnull setstatus("error");
936 f08fdedc 2003-11-23 devnull while(!runq->iflag) Xreturn();
940 c8f53842 2007-03-26 devnull Xerror1(char *s)
942 f08fdedc 2003-11-23 devnull if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0)
943 f08fdedc 2003-11-23 devnull pfmt(err, "rc: %s\n", s);
945 f08fdedc 2003-11-23 devnull pfmt(err, "rc (%s): %s\n", argv0, s);
946 f08fdedc 2003-11-23 devnull flush(err);
947 4ae2f414 2005-08-11 devnull setstatus("error");
948 f08fdedc 2003-11-23 devnull while(!runq->iflag) Xreturn();
952 c8f53842 2007-03-26 devnull setstatus(char *s)
954 f08fdedc 2003-11-23 devnull setvar("status", newword(s, (word *)0));
958 c8f53842 2007-03-26 devnull getstatus(void)
960 c8f53842 2007-03-26 devnull var *status = vlook("status");
961 f08fdedc 2003-11-23 devnull return status->val?status->val->word:"";
965 c8f53842 2007-03-26 devnull truestatus(void)
967 f08fdedc 2003-11-23 devnull char *s;
968 c8f53842 2007-03-26 devnull for(s = getstatus();*s;s++)
969 c8f53842 2007-03-26 devnull if(*s!='|' && *s!='0')
970 c8f53842 2007-03-26 devnull return 0;
971 f08fdedc 2003-11-23 devnull return 1;
975 c8f53842 2007-03-26 devnull Xdelhere(void)
977 f08fdedc 2003-11-23 devnull Unlink(runq->code[runq->pc++].s);
981 c8f53842 2007-03-26 devnull Xfor(void)
983 f08fdedc 2003-11-23 devnull if(runq->argv->words==0){
984 f08fdedc 2003-11-23 devnull poplist();
985 c8f53842 2007-03-26 devnull runq->pc = runq->code[runq->pc].i;
988 f08fdedc 2003-11-23 devnull freelist(runq->local->val);
989 c8f53842 2007-03-26 devnull runq->local->val = runq->argv->words;
990 c8f53842 2007-03-26 devnull runq->local->changed = 1;
991 c8f53842 2007-03-26 devnull runq->argv->words = runq->argv->words->next;
992 c8f53842 2007-03-26 devnull runq->local->val->next = 0;
993 f08fdedc 2003-11-23 devnull runq->pc++;
998 c8f53842 2007-03-26 devnull Xglob(void)
1000 f08fdedc 2003-11-23 devnull globlist();