Blame


1 f08fdedc 2003-11-23 devnull /*
2 f08fdedc 2003-11-23 devnull * Maybe `simple' is a misnomer.
3 f08fdedc 2003-11-23 devnull */
4 f08fdedc 2003-11-23 devnull #include "rc.h"
5 f08fdedc 2003-11-23 devnull #include "getflags.h"
6 f08fdedc 2003-11-23 devnull #include "exec.h"
7 f08fdedc 2003-11-23 devnull #include "io.h"
8 f08fdedc 2003-11-23 devnull #include "fns.h"
9 f08fdedc 2003-11-23 devnull /*
10 f08fdedc 2003-11-23 devnull * Search through the following code to see if we're just going to exit.
11 f08fdedc 2003-11-23 devnull */
12 f08fdedc 2003-11-23 devnull int
13 f08fdedc 2003-11-23 devnull exitnext(void){
14 f08fdedc 2003-11-23 devnull union code *c=&runq->code[runq->pc];
15 f08fdedc 2003-11-23 devnull while(c->f==Xpopredir) c++;
16 f08fdedc 2003-11-23 devnull return c->f==Xexit;
17 f08fdedc 2003-11-23 devnull }
18 f08fdedc 2003-11-23 devnull void Xsimple(void){
19 f08fdedc 2003-11-23 devnull word *a;
20 f08fdedc 2003-11-23 devnull thread *p=runq;
21 f08fdedc 2003-11-23 devnull var *v;
22 f08fdedc 2003-11-23 devnull struct builtin *bp;
23 f08fdedc 2003-11-23 devnull int pid, n;
24 f08fdedc 2003-11-23 devnull char buf[ERRMAX];
25 f08fdedc 2003-11-23 devnull globlist();
26 f08fdedc 2003-11-23 devnull a=runq->argv->words;
27 f08fdedc 2003-11-23 devnull if(a==0){
28 f08fdedc 2003-11-23 devnull Xerror1("empty argument list");
29 f08fdedc 2003-11-23 devnull return;
30 f08fdedc 2003-11-23 devnull }
31 f08fdedc 2003-11-23 devnull if(flag['x'])
32 f08fdedc 2003-11-23 devnull pfmt(err, "%v\n", p->argv->words); /* wrong, should do redirs */
33 f08fdedc 2003-11-23 devnull v=gvlook(a->word);
34 f08fdedc 2003-11-23 devnull if(v->fn)
35 f08fdedc 2003-11-23 devnull execfunc(v);
36 f08fdedc 2003-11-23 devnull else{
37 f08fdedc 2003-11-23 devnull if(strcmp(a->word, "builtin")==0){
38 f08fdedc 2003-11-23 devnull if(count(a)==1){
39 f08fdedc 2003-11-23 devnull pfmt(err, "builtin: empty argument list\n");
40 f08fdedc 2003-11-23 devnull setstatus("empty arg list");
41 f08fdedc 2003-11-23 devnull poplist();
42 f08fdedc 2003-11-23 devnull return;
43 f08fdedc 2003-11-23 devnull }
44 f08fdedc 2003-11-23 devnull a=a->next;
45 f08fdedc 2003-11-23 devnull popword();
46 f08fdedc 2003-11-23 devnull }
47 f08fdedc 2003-11-23 devnull for(bp=Builtin;bp->name;bp++)
48 f08fdedc 2003-11-23 devnull if(strcmp(a->word, bp->name)==0){
49 f08fdedc 2003-11-23 devnull (*bp->fnc)();
50 f08fdedc 2003-11-23 devnull return;
51 f08fdedc 2003-11-23 devnull }
52 f08fdedc 2003-11-23 devnull if(exitnext()){
53 f08fdedc 2003-11-23 devnull /* fork and wait is redundant */
54 f08fdedc 2003-11-23 devnull pushword("exec");
55 f08fdedc 2003-11-23 devnull execexec();
56 f08fdedc 2003-11-23 devnull Xexit();
57 f08fdedc 2003-11-23 devnull }
58 f08fdedc 2003-11-23 devnull else{
59 f08fdedc 2003-11-23 devnull flush(err);
60 f08fdedc 2003-11-23 devnull Updenv(); /* necessary so changes don't go out again */
61 f08fdedc 2003-11-23 devnull switch(pid=fork()){
62 f08fdedc 2003-11-23 devnull case -1:
63 f08fdedc 2003-11-23 devnull Xerror("try again");
64 f08fdedc 2003-11-23 devnull return;
65 f08fdedc 2003-11-23 devnull case 0:
66 69ab5d3d 2004-03-26 devnull rfork(RFNOTEG);
67 f08fdedc 2003-11-23 devnull pushword("exec");
68 f08fdedc 2003-11-23 devnull execexec();
69 f08fdedc 2003-11-23 devnull strcpy(buf, "can't exec: ");
70 f08fdedc 2003-11-23 devnull n = strlen(buf);
71 f08fdedc 2003-11-23 devnull errstr(buf+n, ERRMAX-n);
72 f08fdedc 2003-11-23 devnull Exit(buf);
73 f08fdedc 2003-11-23 devnull default:
74 69ab5d3d 2004-03-26 devnull kidpid = pid;
75 f08fdedc 2003-11-23 devnull poplist();
76 f08fdedc 2003-11-23 devnull /* interrupts don't get us out */
77 f08fdedc 2003-11-23 devnull while(Waitfor(pid, 1) < 0)
78 f08fdedc 2003-11-23 devnull ;
79 69ab5d3d 2004-03-26 devnull kidpid = 0;
80 f08fdedc 2003-11-23 devnull }
81 f08fdedc 2003-11-23 devnull }
82 f08fdedc 2003-11-23 devnull }
83 f08fdedc 2003-11-23 devnull }
84 f08fdedc 2003-11-23 devnull struct word nullpath={ "", 0};
85 f08fdedc 2003-11-23 devnull void doredir(redir *rp)
86 f08fdedc 2003-11-23 devnull {
87 f08fdedc 2003-11-23 devnull if(rp){
88 f08fdedc 2003-11-23 devnull doredir(rp->next);
89 f08fdedc 2003-11-23 devnull switch(rp->type){
90 f08fdedc 2003-11-23 devnull case ROPEN:
91 f08fdedc 2003-11-23 devnull if(rp->from!=rp->to){
92 f08fdedc 2003-11-23 devnull Dup(rp->from, rp->to);
93 f08fdedc 2003-11-23 devnull close(rp->from);
94 f08fdedc 2003-11-23 devnull }
95 f08fdedc 2003-11-23 devnull break;
96 f08fdedc 2003-11-23 devnull case RDUP: Dup(rp->from, rp->to); break;
97 f08fdedc 2003-11-23 devnull case RCLOSE: close(rp->from); break;
98 f08fdedc 2003-11-23 devnull }
99 f08fdedc 2003-11-23 devnull }
100 f08fdedc 2003-11-23 devnull }
101 f08fdedc 2003-11-23 devnull word *searchpath(char *w){
102 f08fdedc 2003-11-23 devnull word *path;
103 f08fdedc 2003-11-23 devnull if(strncmp(w, "/", 1)==0
104 f08fdedc 2003-11-23 devnull || strncmp(w, "#", 1)==0
105 f08fdedc 2003-11-23 devnull || strncmp(w, "./", 2)==0
106 f08fdedc 2003-11-23 devnull || strncmp(w, "../", 3)==0
107 f08fdedc 2003-11-23 devnull || (path=vlook("path")->val)==0)
108 f08fdedc 2003-11-23 devnull path=&nullpath;
109 f08fdedc 2003-11-23 devnull return path;
110 f08fdedc 2003-11-23 devnull }
111 f08fdedc 2003-11-23 devnull void execexec(void){
112 f08fdedc 2003-11-23 devnull popword(); /* "exec" */
113 f08fdedc 2003-11-23 devnull if(runq->argv->words==0){
114 f08fdedc 2003-11-23 devnull Xerror1("empty argument list");
115 f08fdedc 2003-11-23 devnull return;
116 f08fdedc 2003-11-23 devnull }
117 f08fdedc 2003-11-23 devnull doredir(runq->redir);
118 f08fdedc 2003-11-23 devnull Execute(runq->argv->words, searchpath(runq->argv->words->word));
119 f08fdedc 2003-11-23 devnull poplist();
120 f08fdedc 2003-11-23 devnull }
121 f08fdedc 2003-11-23 devnull void execfunc(var *func)
122 f08fdedc 2003-11-23 devnull {
123 f08fdedc 2003-11-23 devnull word *starval;
124 f08fdedc 2003-11-23 devnull popword();
125 f08fdedc 2003-11-23 devnull starval=runq->argv->words;
126 f08fdedc 2003-11-23 devnull runq->argv->words=0;
127 f08fdedc 2003-11-23 devnull poplist();
128 f08fdedc 2003-11-23 devnull start(func->fn, func->pc, (struct var *)0);
129 f08fdedc 2003-11-23 devnull runq->local=newvar(strdup("*"), runq->local);
130 f08fdedc 2003-11-23 devnull runq->local->val=starval;
131 f08fdedc 2003-11-23 devnull runq->local->changed=1;
132 f08fdedc 2003-11-23 devnull }
133 f08fdedc 2003-11-23 devnull int dochdir(char *word){
134 f08fdedc 2003-11-23 devnull /* report to /dev/wdir if it exists and we're interactive */
135 f08fdedc 2003-11-23 devnull static int wdirfd = -2;
136 f08fdedc 2003-11-23 devnull if(chdir(word)<0) return -1;
137 f08fdedc 2003-11-23 devnull if(flag['i']!=0){
138 f08fdedc 2003-11-23 devnull if(wdirfd==-2) /* try only once */
139 f08fdedc 2003-11-23 devnull wdirfd = open("/dev/wdir", OWRITE|OCEXEC);
140 f08fdedc 2003-11-23 devnull if(wdirfd>=0)
141 f08fdedc 2003-11-23 devnull write(wdirfd, word, strlen(word));
142 f08fdedc 2003-11-23 devnull }
143 f08fdedc 2003-11-23 devnull return 1;
144 f08fdedc 2003-11-23 devnull }
145 f08fdedc 2003-11-23 devnull void execcd(void){
146 f08fdedc 2003-11-23 devnull word *a=runq->argv->words;
147 f08fdedc 2003-11-23 devnull word *cdpath;
148 f08fdedc 2003-11-23 devnull char dir[512];
149 f08fdedc 2003-11-23 devnull setstatus("can't cd");
150 f08fdedc 2003-11-23 devnull cdpath=vlook("cdpath")->val;
151 f08fdedc 2003-11-23 devnull switch(count(a)){
152 f08fdedc 2003-11-23 devnull default:
153 f08fdedc 2003-11-23 devnull pfmt(err, "Usage: cd [directory]\n");
154 f08fdedc 2003-11-23 devnull break;
155 f08fdedc 2003-11-23 devnull case 2:
156 f08fdedc 2003-11-23 devnull if(a->next->word[0]=='/' || cdpath==0) cdpath=&nullpath;
157 f08fdedc 2003-11-23 devnull for(;cdpath;cdpath=cdpath->next){
158 f08fdedc 2003-11-23 devnull strcpy(dir, cdpath->word);
159 f08fdedc 2003-11-23 devnull if(dir[0]) strcat(dir, "/");
160 f08fdedc 2003-11-23 devnull strcat(dir, a->next->word);
161 f08fdedc 2003-11-23 devnull if(dochdir(dir)>=0){
162 f08fdedc 2003-11-23 devnull if(strlen(cdpath->word)
163 f08fdedc 2003-11-23 devnull && strcmp(cdpath->word, ".")!=0)
164 f08fdedc 2003-11-23 devnull pfmt(err, "%s\n", dir);
165 f08fdedc 2003-11-23 devnull setstatus("");
166 f08fdedc 2003-11-23 devnull break;
167 f08fdedc 2003-11-23 devnull }
168 f08fdedc 2003-11-23 devnull }
169 f08fdedc 2003-11-23 devnull if(cdpath==0) pfmt(err, "Can't cd %s: %r\n", a->next->word);
170 f08fdedc 2003-11-23 devnull break;
171 f08fdedc 2003-11-23 devnull case 1:
172 f08fdedc 2003-11-23 devnull a=vlook("home")->val;
173 f08fdedc 2003-11-23 devnull if(count(a)>=1){
174 f08fdedc 2003-11-23 devnull if(dochdir(a->word)>=0)
175 f08fdedc 2003-11-23 devnull setstatus("");
176 f08fdedc 2003-11-23 devnull else
177 f08fdedc 2003-11-23 devnull pfmt(err, "Can't cd %s: %r\n", a->word);
178 f08fdedc 2003-11-23 devnull }
179 f08fdedc 2003-11-23 devnull else
180 f08fdedc 2003-11-23 devnull pfmt(err, "Can't cd -- $home empty\n");
181 f08fdedc 2003-11-23 devnull break;
182 f08fdedc 2003-11-23 devnull }
183 f08fdedc 2003-11-23 devnull poplist();
184 f08fdedc 2003-11-23 devnull }
185 f08fdedc 2003-11-23 devnull void execexit(void){
186 f08fdedc 2003-11-23 devnull switch(count(runq->argv->words)){
187 f08fdedc 2003-11-23 devnull default: pfmt(err, "Usage: exit [status]\nExiting anyway\n");
188 f08fdedc 2003-11-23 devnull case 2: setstatus(runq->argv->words->next->word);
189 f08fdedc 2003-11-23 devnull case 1: Xexit();
190 f08fdedc 2003-11-23 devnull }
191 f08fdedc 2003-11-23 devnull }
192 f08fdedc 2003-11-23 devnull void execshift(void){
193 f08fdedc 2003-11-23 devnull int n;
194 f08fdedc 2003-11-23 devnull word *a;
195 f08fdedc 2003-11-23 devnull var *star;
196 f08fdedc 2003-11-23 devnull switch(count(runq->argv->words)){
197 f08fdedc 2003-11-23 devnull default:
198 f08fdedc 2003-11-23 devnull pfmt(err, "Usage: shift [n]\n");
199 f08fdedc 2003-11-23 devnull setstatus("shift usage");
200 f08fdedc 2003-11-23 devnull poplist();
201 f08fdedc 2003-11-23 devnull return;
202 f08fdedc 2003-11-23 devnull case 2: n=atoi(runq->argv->words->next->word); break;
203 f08fdedc 2003-11-23 devnull case 1: n=1; break;
204 f08fdedc 2003-11-23 devnull }
205 f08fdedc 2003-11-23 devnull star=vlook("*");
206 f08fdedc 2003-11-23 devnull for(;n && star->val;--n){
207 f08fdedc 2003-11-23 devnull a=star->val->next;
208 f08fdedc 2003-11-23 devnull efree(star->val->word);
209 f08fdedc 2003-11-23 devnull efree((char *)star->val);
210 f08fdedc 2003-11-23 devnull star->val=a;
211 f08fdedc 2003-11-23 devnull star->changed=1;
212 f08fdedc 2003-11-23 devnull }
213 f08fdedc 2003-11-23 devnull setstatus("");
214 f08fdedc 2003-11-23 devnull poplist();
215 f08fdedc 2003-11-23 devnull }
216 f08fdedc 2003-11-23 devnull int octal(char *s)
217 f08fdedc 2003-11-23 devnull {
218 f08fdedc 2003-11-23 devnull int n=0;
219 f08fdedc 2003-11-23 devnull while(*s==' ' || *s=='\t' || *s=='\n') s++;
220 f08fdedc 2003-11-23 devnull while('0'<=*s && *s<='7') n=n*8+*s++-'0';
221 f08fdedc 2003-11-23 devnull return n;
222 f08fdedc 2003-11-23 devnull }
223 f08fdedc 2003-11-23 devnull int mapfd(int fd)
224 f08fdedc 2003-11-23 devnull {
225 f08fdedc 2003-11-23 devnull redir *rp;
226 f08fdedc 2003-11-23 devnull for(rp=runq->redir;rp;rp=rp->next){
227 f08fdedc 2003-11-23 devnull switch(rp->type){
228 f08fdedc 2003-11-23 devnull case RCLOSE:
229 f08fdedc 2003-11-23 devnull if(rp->from==fd) fd=-1;
230 f08fdedc 2003-11-23 devnull break;
231 f08fdedc 2003-11-23 devnull case RDUP:
232 f08fdedc 2003-11-23 devnull case ROPEN:
233 f08fdedc 2003-11-23 devnull if(rp->to==fd) fd=rp->from;
234 f08fdedc 2003-11-23 devnull break;
235 f08fdedc 2003-11-23 devnull }
236 f08fdedc 2003-11-23 devnull }
237 f08fdedc 2003-11-23 devnull return fd;
238 f08fdedc 2003-11-23 devnull }
239 f08fdedc 2003-11-23 devnull union code rdcmds[4];
240 f08fdedc 2003-11-23 devnull void execcmds(io *f)
241 f08fdedc 2003-11-23 devnull {
242 f08fdedc 2003-11-23 devnull static int first=1;
243 f08fdedc 2003-11-23 devnull if(first){
244 f08fdedc 2003-11-23 devnull rdcmds[0].i=1;
245 f08fdedc 2003-11-23 devnull rdcmds[1].f=Xrdcmds;
246 f08fdedc 2003-11-23 devnull rdcmds[2].f=Xreturn;
247 f08fdedc 2003-11-23 devnull first=0;
248 f08fdedc 2003-11-23 devnull }
249 f08fdedc 2003-11-23 devnull start(rdcmds, 1, runq->local);
250 f08fdedc 2003-11-23 devnull runq->cmdfd=f;
251 f08fdedc 2003-11-23 devnull runq->iflast=0;
252 f08fdedc 2003-11-23 devnull }
253 f08fdedc 2003-11-23 devnull void execeval(void){
254 f08fdedc 2003-11-23 devnull char *cmdline, *s, *t;
255 f08fdedc 2003-11-23 devnull int len=0;
256 f08fdedc 2003-11-23 devnull word *ap;
257 f08fdedc 2003-11-23 devnull if(count(runq->argv->words)<=1){
258 f08fdedc 2003-11-23 devnull Xerror1("Usage: eval cmd ...");
259 f08fdedc 2003-11-23 devnull return;
260 f08fdedc 2003-11-23 devnull }
261 f08fdedc 2003-11-23 devnull eflagok=1;
262 f08fdedc 2003-11-23 devnull for(ap=runq->argv->words->next;ap;ap=ap->next)
263 f08fdedc 2003-11-23 devnull len+=1+strlen(ap->word);
264 f08fdedc 2003-11-23 devnull cmdline=emalloc(len);
265 f08fdedc 2003-11-23 devnull s=cmdline;
266 f08fdedc 2003-11-23 devnull for(ap=runq->argv->words->next;ap;ap=ap->next){
267 f08fdedc 2003-11-23 devnull for(t=ap->word;*t;) *s++=*t++;
268 f08fdedc 2003-11-23 devnull *s++=' ';
269 f08fdedc 2003-11-23 devnull }
270 f08fdedc 2003-11-23 devnull s[-1]='\n';
271 f08fdedc 2003-11-23 devnull poplist();
272 f08fdedc 2003-11-23 devnull execcmds(opencore(cmdline, len));
273 f08fdedc 2003-11-23 devnull efree(cmdline);
274 f08fdedc 2003-11-23 devnull }
275 f08fdedc 2003-11-23 devnull union code dotcmds[14];
276 f08fdedc 2003-11-23 devnull void execdot(void){
277 f08fdedc 2003-11-23 devnull int iflag=0;
278 f08fdedc 2003-11-23 devnull int fd;
279 f08fdedc 2003-11-23 devnull list *av;
280 f08fdedc 2003-11-23 devnull thread *p=runq;
281 f08fdedc 2003-11-23 devnull char *zero;
282 f08fdedc 2003-11-23 devnull static int first=1;
283 f08fdedc 2003-11-23 devnull char file[512];
284 f08fdedc 2003-11-23 devnull word *path;
285 f08fdedc 2003-11-23 devnull if(first){
286 f08fdedc 2003-11-23 devnull dotcmds[0].i=1;
287 f08fdedc 2003-11-23 devnull dotcmds[1].f=Xmark;
288 f08fdedc 2003-11-23 devnull dotcmds[2].f=Xword;
289 f08fdedc 2003-11-23 devnull dotcmds[3].s="0";
290 f08fdedc 2003-11-23 devnull dotcmds[4].f=Xlocal;
291 f08fdedc 2003-11-23 devnull dotcmds[5].f=Xmark;
292 f08fdedc 2003-11-23 devnull dotcmds[6].f=Xword;
293 f08fdedc 2003-11-23 devnull dotcmds[7].s="*";
294 f08fdedc 2003-11-23 devnull dotcmds[8].f=Xlocal;
295 f08fdedc 2003-11-23 devnull dotcmds[9].f=Xrdcmds;
296 f08fdedc 2003-11-23 devnull dotcmds[10].f=Xunlocal;
297 f08fdedc 2003-11-23 devnull dotcmds[11].f=Xunlocal;
298 f08fdedc 2003-11-23 devnull dotcmds[12].f=Xreturn;
299 f08fdedc 2003-11-23 devnull first=0;
300 f08fdedc 2003-11-23 devnull }
301 f08fdedc 2003-11-23 devnull else
302 f08fdedc 2003-11-23 devnull eflagok=1;
303 f08fdedc 2003-11-23 devnull popword();
304 f08fdedc 2003-11-23 devnull if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){
305 f08fdedc 2003-11-23 devnull iflag=1;
306 f08fdedc 2003-11-23 devnull popword();
307 f08fdedc 2003-11-23 devnull }
308 f08fdedc 2003-11-23 devnull /* get input file */
309 f08fdedc 2003-11-23 devnull if(p->argv->words==0){
310 f08fdedc 2003-11-23 devnull Xerror1("Usage: . [-i] file [arg ...]");
311 f08fdedc 2003-11-23 devnull return;
312 f08fdedc 2003-11-23 devnull }
313 f08fdedc 2003-11-23 devnull zero=strdup(p->argv->words->word);
314 f08fdedc 2003-11-23 devnull popword();
315 f08fdedc 2003-11-23 devnull fd=-1;
316 f08fdedc 2003-11-23 devnull for(path=searchpath(zero);path;path=path->next){
317 f08fdedc 2003-11-23 devnull strcpy(file, path->word);
318 f08fdedc 2003-11-23 devnull if(file[0]) strcat(file, "/");
319 f08fdedc 2003-11-23 devnull strcat(file, zero);
320 f08fdedc 2003-11-23 devnull if((fd=open(file, 0))>=0) break;
321 f08fdedc 2003-11-23 devnull if(strcmp(file, "/dev/stdin")==0){ /* for sun & ucb */
322 f08fdedc 2003-11-23 devnull fd=Dup1(0);
323 f08fdedc 2003-11-23 devnull if(fd>=0) break;
324 f08fdedc 2003-11-23 devnull }
325 f08fdedc 2003-11-23 devnull }
326 f08fdedc 2003-11-23 devnull if(fd<0){
327 f08fdedc 2003-11-23 devnull pfmt(err, "%s: ", zero);
328 f08fdedc 2003-11-23 devnull setstatus("can't open");
329 f08fdedc 2003-11-23 devnull Xerror(".: can't open");
330 f08fdedc 2003-11-23 devnull return;
331 f08fdedc 2003-11-23 devnull }
332 f08fdedc 2003-11-23 devnull /* set up for a new command loop */
333 f08fdedc 2003-11-23 devnull start(dotcmds, 1, (struct var *)0);
334 f08fdedc 2003-11-23 devnull pushredir(RCLOSE, fd, 0);
335 f08fdedc 2003-11-23 devnull runq->cmdfile=zero;
336 f08fdedc 2003-11-23 devnull runq->cmdfd=openfd(fd);
337 f08fdedc 2003-11-23 devnull runq->iflag=iflag;
338 f08fdedc 2003-11-23 devnull runq->iflast=0;
339 f08fdedc 2003-11-23 devnull /* push $* value */
340 f08fdedc 2003-11-23 devnull pushlist();
341 f08fdedc 2003-11-23 devnull runq->argv->words=p->argv->words;
342 f08fdedc 2003-11-23 devnull /* free caller's copy of $* */
343 f08fdedc 2003-11-23 devnull av=p->argv;
344 f08fdedc 2003-11-23 devnull p->argv=av->next;
345 f08fdedc 2003-11-23 devnull efree((char *)av);
346 f08fdedc 2003-11-23 devnull /* push $0 value */
347 f08fdedc 2003-11-23 devnull pushlist();
348 f08fdedc 2003-11-23 devnull pushword(zero);
349 f08fdedc 2003-11-23 devnull ndot++;
350 f08fdedc 2003-11-23 devnull }
351 f08fdedc 2003-11-23 devnull void execflag(void){
352 f08fdedc 2003-11-23 devnull char *letter, *val;
353 f08fdedc 2003-11-23 devnull switch(count(runq->argv->words)){
354 f08fdedc 2003-11-23 devnull case 2:
355 f08fdedc 2003-11-23 devnull setstatus(flag[(uchar)runq->argv->words->next->word[0]]?"":"flag not set");
356 f08fdedc 2003-11-23 devnull break;
357 f08fdedc 2003-11-23 devnull case 3:
358 f08fdedc 2003-11-23 devnull letter=runq->argv->words->next->word;
359 f08fdedc 2003-11-23 devnull val=runq->argv->words->next->next->word;
360 f08fdedc 2003-11-23 devnull if(strlen(letter)==1){
361 f08fdedc 2003-11-23 devnull if(strcmp(val, "+")==0){
362 f08fdedc 2003-11-23 devnull flag[(uchar)letter[0]]=flagset;
363 f08fdedc 2003-11-23 devnull break;
364 f08fdedc 2003-11-23 devnull }
365 f08fdedc 2003-11-23 devnull if(strcmp(val, "-")==0){
366 f08fdedc 2003-11-23 devnull flag[(uchar)letter[0]]=0;
367 f08fdedc 2003-11-23 devnull break;
368 f08fdedc 2003-11-23 devnull }
369 f08fdedc 2003-11-23 devnull }
370 f08fdedc 2003-11-23 devnull default:
371 f08fdedc 2003-11-23 devnull Xerror1("Usage: flag [letter] [+-]");
372 f08fdedc 2003-11-23 devnull return;
373 f08fdedc 2003-11-23 devnull }
374 f08fdedc 2003-11-23 devnull poplist();
375 f08fdedc 2003-11-23 devnull }
376 f08fdedc 2003-11-23 devnull void execwhatis(void){ /* mildly wrong -- should fork before writing */
377 f08fdedc 2003-11-23 devnull word *a, *b, *path;
378 f08fdedc 2003-11-23 devnull var *v;
379 f08fdedc 2003-11-23 devnull struct builtin *bp;
380 f08fdedc 2003-11-23 devnull char file[512];
381 f08fdedc 2003-11-23 devnull struct io out[1];
382 f08fdedc 2003-11-23 devnull int found, sep;
383 f08fdedc 2003-11-23 devnull a=runq->argv->words->next;
384 f08fdedc 2003-11-23 devnull if(a==0){
385 f08fdedc 2003-11-23 devnull Xerror1("Usage: whatis name ...");
386 f08fdedc 2003-11-23 devnull return;
387 f08fdedc 2003-11-23 devnull }
388 f08fdedc 2003-11-23 devnull setstatus("");
389 f08fdedc 2003-11-23 devnull out->fd=mapfd(1);
390 f08fdedc 2003-11-23 devnull out->bufp=out->buf;
391 f08fdedc 2003-11-23 devnull out->ebuf=&out->buf[NBUF];
392 f08fdedc 2003-11-23 devnull out->strp=0;
393 f08fdedc 2003-11-23 devnull for(;a;a=a->next){
394 f08fdedc 2003-11-23 devnull v=vlook(a->word);
395 f08fdedc 2003-11-23 devnull if(v->val){
396 f08fdedc 2003-11-23 devnull pfmt(out, "%s=", a->word);
397 f08fdedc 2003-11-23 devnull if(v->val->next==0)
398 f08fdedc 2003-11-23 devnull pfmt(out, "%q\n", v->val->word);
399 f08fdedc 2003-11-23 devnull else{
400 f08fdedc 2003-11-23 devnull sep='(';
401 f08fdedc 2003-11-23 devnull for(b=v->val;b && b->word;b=b->next){
402 f08fdedc 2003-11-23 devnull pfmt(out, "%c%q", sep, b->word);
403 f08fdedc 2003-11-23 devnull sep=' ';
404 f08fdedc 2003-11-23 devnull }
405 f08fdedc 2003-11-23 devnull pfmt(out, ")\n");
406 f08fdedc 2003-11-23 devnull }
407 f08fdedc 2003-11-23 devnull found=1;
408 f08fdedc 2003-11-23 devnull }
409 f08fdedc 2003-11-23 devnull else
410 f08fdedc 2003-11-23 devnull found=0;
411 f08fdedc 2003-11-23 devnull v=gvlook(a->word);
412 f08fdedc 2003-11-23 devnull if(v->fn) pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s);
413 f08fdedc 2003-11-23 devnull else{
414 f08fdedc 2003-11-23 devnull for(bp=Builtin;bp->name;bp++)
415 f08fdedc 2003-11-23 devnull if(strcmp(a->word, bp->name)==0){
416 f08fdedc 2003-11-23 devnull pfmt(out, "builtin %s\n", a->word);
417 f08fdedc 2003-11-23 devnull break;
418 f08fdedc 2003-11-23 devnull }
419 f08fdedc 2003-11-23 devnull if(!bp->name){
420 f08fdedc 2003-11-23 devnull for(path=searchpath(a->word);path;path=path->next){
421 f08fdedc 2003-11-23 devnull strcpy(file, path->word);
422 f08fdedc 2003-11-23 devnull if(file[0]) strcat(file, "/");
423 f08fdedc 2003-11-23 devnull strcat(file, a->word);
424 f08fdedc 2003-11-23 devnull if(Executable(file)){
425 f08fdedc 2003-11-23 devnull pfmt(out, "%s\n", file);
426 f08fdedc 2003-11-23 devnull break;
427 f08fdedc 2003-11-23 devnull }
428 f08fdedc 2003-11-23 devnull }
429 f08fdedc 2003-11-23 devnull if(!path && !found){
430 f08fdedc 2003-11-23 devnull pfmt(err, "%s: not found\n", a->word);
431 f08fdedc 2003-11-23 devnull setstatus("not found");
432 f08fdedc 2003-11-23 devnull }
433 f08fdedc 2003-11-23 devnull }
434 f08fdedc 2003-11-23 devnull }
435 f08fdedc 2003-11-23 devnull }
436 f08fdedc 2003-11-23 devnull poplist();
437 f08fdedc 2003-11-23 devnull flush(err);
438 f08fdedc 2003-11-23 devnull }
439 f08fdedc 2003-11-23 devnull void execwait(void){
440 f08fdedc 2003-11-23 devnull switch(count(runq->argv->words)){
441 f08fdedc 2003-11-23 devnull default: Xerror1("Usage: wait [pid]"); return;
442 f08fdedc 2003-11-23 devnull case 2: Waitfor(atoi(runq->argv->words->next->word), 0); break;
443 f08fdedc 2003-11-23 devnull case 1: Waitfor(-1, 0); break;
444 f08fdedc 2003-11-23 devnull }
445 f08fdedc 2003-11-23 devnull poplist();
446 f08fdedc 2003-11-23 devnull }