1 7c709434 2005-03-18 devnull #include <u.h>
2 7c709434 2005-03-18 devnull #include <libc.h>
3 7c709434 2005-03-18 devnull #include <thread.h>
4 7c709434 2005-03-18 devnull #include <9pclient.h>
5 7c709434 2005-03-18 devnull #include "acme.h"
7 7c709434 2005-03-18 devnull extern int *xxx;
8 7c709434 2005-03-18 devnull static CFsys *acmefs;
9 7c709434 2005-03-18 devnull Win *windows;
10 7c709434 2005-03-18 devnull static Win *last;
13 7c709434 2005-03-18 devnull mountacme(void)
15 7c709434 2005-03-18 devnull if(acmefs == nil){
16 7c709434 2005-03-18 devnull acmefs = nsmount("acme", nil);
17 7c709434 2005-03-18 devnull if(acmefs == nil)
18 7c709434 2005-03-18 devnull sysfatal("cannot mount acme: %r");
23 7c709434 2005-03-18 devnull newwin(void)
26 7c709434 2005-03-18 devnull CFid *fid;
27 7c709434 2005-03-18 devnull char buf[100];
28 7c709434 2005-03-18 devnull int id, n;
30 7c709434 2005-03-18 devnull mountacme();
31 7c709434 2005-03-18 devnull fid = fsopen(acmefs, "new/ctl", ORDWR);
32 7c709434 2005-03-18 devnull if(fid == nil)
33 7c709434 2005-03-18 devnull sysfatal("open new/ctl: %r");
34 7c709434 2005-03-18 devnull n = fsread(fid, buf, sizeof buf-1);
35 7c709434 2005-03-18 devnull if(n <= 0)
36 7c709434 2005-03-18 devnull sysfatal("read new/ctl: %r");
37 7c709434 2005-03-18 devnull buf[n] = 0;
38 7c709434 2005-03-18 devnull id = atoi(buf);
39 7c709434 2005-03-18 devnull if(id == 0)
40 7c709434 2005-03-18 devnull sysfatal("read new/ctl: malformed message: %s", buf);
42 7c709434 2005-03-18 devnull w = emalloc(sizeof *w);
43 7c709434 2005-03-18 devnull w->id = id;
44 7c709434 2005-03-18 devnull w->ctl = fid;
45 7c709434 2005-03-18 devnull w->next = nil;
46 7c709434 2005-03-18 devnull w->prev = last;
48 7c709434 2005-03-18 devnull last->next = w;
50 7c709434 2005-03-18 devnull windows = w;
51 7c709434 2005-03-18 devnull last = w;
52 7c709434 2005-03-18 devnull return w;
56 7c709434 2005-03-18 devnull winclosefiles(Win *w)
58 7c709434 2005-03-18 devnull if(w->ctl){
59 7c709434 2005-03-18 devnull fsclose(w->ctl);
60 7c709434 2005-03-18 devnull w->ctl = nil;
62 7c709434 2005-03-18 devnull if(w->body){
63 7c709434 2005-03-18 devnull fsclose(w->body);
64 7c709434 2005-03-18 devnull w->body = nil;
66 7c709434 2005-03-18 devnull if(w->addr){
67 7c709434 2005-03-18 devnull fsclose(w->addr);
68 7c709434 2005-03-18 devnull w->addr = nil;
70 7c709434 2005-03-18 devnull if(w->tag){
71 7c709434 2005-03-18 devnull fsclose(w->tag);
72 7c709434 2005-03-18 devnull w->tag = nil;
74 7c709434 2005-03-18 devnull if(w->event){
75 7c709434 2005-03-18 devnull fsclose(w->event);
76 7c709434 2005-03-18 devnull w->event = nil;
78 7c709434 2005-03-18 devnull if(w->data){
79 7c709434 2005-03-18 devnull fsclose(w->data);
80 7c709434 2005-03-18 devnull w->data = nil;
82 7c709434 2005-03-18 devnull if(w->xdata){
83 7c709434 2005-03-18 devnull fsclose(w->xdata);
84 7c709434 2005-03-18 devnull w->xdata = nil;
89 7c709434 2005-03-18 devnull winfree(Win *w)
91 7c709434 2005-03-18 devnull winclosefiles(w);
92 7c709434 2005-03-18 devnull if(w->c){
93 7c709434 2005-03-18 devnull chanfree(w->c);
94 7c709434 2005-03-18 devnull w->c = nil;
96 7c709434 2005-03-18 devnull if(w->next)
97 7c709434 2005-03-18 devnull w->next->prev = w->prev;
99 7c709434 2005-03-18 devnull last = w->prev;
100 7c709434 2005-03-18 devnull if(w->prev)
101 7c709434 2005-03-18 devnull w->prev->next = w->next;
103 7c709434 2005-03-18 devnull windows = w->next;
104 7c709434 2005-03-18 devnull free(w);
108 7c709434 2005-03-18 devnull windeleteall(void)
110 7c709434 2005-03-18 devnull Win *w, *next;
112 7c709434 2005-03-18 devnull for(w=windows; w; w=next){
113 7c709434 2005-03-18 devnull next = w->next;
114 7c709434 2005-03-18 devnull winctl(w, "delete");
118 7c709434 2005-03-18 devnull static CFid*
119 7c709434 2005-03-18 devnull wfid(Win *w, char *name)
121 7c709434 2005-03-18 devnull char buf[100];
122 7c709434 2005-03-18 devnull CFid **fid;
124 7c709434 2005-03-18 devnull if(strcmp(name, "ctl") == 0)
125 7c709434 2005-03-18 devnull fid = &w->ctl;
126 7c709434 2005-03-18 devnull else if(strcmp(name, "body") == 0)
127 7c709434 2005-03-18 devnull fid = &w->body;
128 7c709434 2005-03-18 devnull else if(strcmp(name, "addr") == 0)
129 7c709434 2005-03-18 devnull fid = &w->addr;
130 7c709434 2005-03-18 devnull else if(strcmp(name, "tag") == 0)
131 7c709434 2005-03-18 devnull fid = &w->tag;
132 7c709434 2005-03-18 devnull else if(strcmp(name, "event") == 0)
133 7c709434 2005-03-18 devnull fid = &w->event;
134 7c709434 2005-03-18 devnull else if(strcmp(name, "data") == 0)
135 7c709434 2005-03-18 devnull fid = &w->data;
136 7c709434 2005-03-18 devnull else if(strcmp(name, "xdata") == 0)
137 7c709434 2005-03-18 devnull fid = &w->xdata;
139 7c709434 2005-03-18 devnull fid = 0;
140 7c709434 2005-03-18 devnull sysfatal("bad window file name %s", name);
143 7c709434 2005-03-18 devnull if(*fid == nil){
144 7c709434 2005-03-18 devnull snprint(buf, sizeof buf, "acme/%d/%s", w->id, name);
145 7c709434 2005-03-18 devnull *fid = fsopen(acmefs, buf, ORDWR);
146 7c709434 2005-03-18 devnull if(*fid == nil)
147 7c709434 2005-03-18 devnull sysfatal("open %s: %r", buf);
149 7c709434 2005-03-18 devnull return *fid;
153 7c709434 2005-03-18 devnull winopenfd(Win *w, char *name, int mode)
155 7c709434 2005-03-18 devnull char buf[100];
157 7c709434 2005-03-18 devnull snprint(buf, sizeof buf, "%d/%s", w->id, name);
158 7c709434 2005-03-18 devnull return fsopenfd(acmefs, buf, mode);
162 7c709434 2005-03-18 devnull winctl(Win *w, char *fmt, ...)
164 7c709434 2005-03-18 devnull char *s;
165 7c709434 2005-03-18 devnull va_list arg;
166 7c709434 2005-03-18 devnull CFid *fid;
169 7c709434 2005-03-18 devnull va_start(arg, fmt);
170 7c709434 2005-03-18 devnull s = evsmprint(fmt, arg);
171 7c709434 2005-03-18 devnull va_end(arg);
173 7c709434 2005-03-18 devnull fid = wfid(w, "ctl");
174 7c709434 2005-03-18 devnull n = fspwrite(fid, s, strlen(s), 0);
175 7c709434 2005-03-18 devnull free(s);
176 7c709434 2005-03-18 devnull return n;
180 7c709434 2005-03-18 devnull winname(Win *w, char *fmt, ...)
182 7c709434 2005-03-18 devnull char *s;
183 7c709434 2005-03-18 devnull va_list arg;
186 7c709434 2005-03-18 devnull va_start(arg, fmt);
187 7c709434 2005-03-18 devnull s = evsmprint(fmt, arg);
188 7c709434 2005-03-18 devnull va_end(arg);
190 7c709434 2005-03-18 devnull n = winctl(w, "name %s\n", s);
191 7c709434 2005-03-18 devnull free(s);
192 7c709434 2005-03-18 devnull return n;
196 7c709434 2005-03-18 devnull winprint(Win *w, char *name, char *fmt, ...)
198 7c709434 2005-03-18 devnull char *s;
199 7c709434 2005-03-18 devnull va_list arg;
202 7c709434 2005-03-18 devnull va_start(arg, fmt);
203 7c709434 2005-03-18 devnull s = evsmprint(fmt, arg);
204 7c709434 2005-03-18 devnull va_end(arg);
206 7c709434 2005-03-18 devnull n = fswrite(wfid(w, name), s, strlen(s));
207 7c709434 2005-03-18 devnull free(s);
208 7c709434 2005-03-18 devnull return n;
212 7c709434 2005-03-18 devnull winaddr(Win *w, char *fmt, ...)
214 7c709434 2005-03-18 devnull char *s;
215 7c709434 2005-03-18 devnull va_list arg;
218 7c709434 2005-03-18 devnull va_start(arg, fmt);
219 7c709434 2005-03-18 devnull s = evsmprint(fmt, arg);
220 7c709434 2005-03-18 devnull va_end(arg);
222 7c709434 2005-03-18 devnull n = fswrite(wfid(w, "addr"), s, strlen(s));
223 7c709434 2005-03-18 devnull free(s);
224 7c709434 2005-03-18 devnull return n;
228 7c709434 2005-03-18 devnull winreadaddr(Win *w, uint *q1)
230 7c709434 2005-03-18 devnull char buf[40], *p;
231 7c709434 2005-03-18 devnull uint q0;
234 7c709434 2005-03-18 devnull n = fspread(wfid(w, "addr"), buf, sizeof buf-1, 0);
235 7c709434 2005-03-18 devnull if(n <= 0)
236 7c709434 2005-03-18 devnull return -1;
237 7c709434 2005-03-18 devnull buf[n] = 0;
238 7c709434 2005-03-18 devnull q0 = strtoul(buf, &p, 10);
240 7c709434 2005-03-18 devnull *q1 = strtoul(p, nil, 10);
241 7c709434 2005-03-18 devnull return q0;
245 7c709434 2005-03-18 devnull winread(Win *w, char *file, void *a, int n)
247 7c709434 2005-03-18 devnull return fspread(wfid(w, file), a, n, 0);
251 7c709434 2005-03-18 devnull winwrite(Win *w, char *file, void *a, int n)
253 7c709434 2005-03-18 devnull return fswrite(wfid(w, file), a, n);
257 7c709434 2005-03-18 devnull fsreadm(CFid *fid)
259 7c709434 2005-03-18 devnull char *buf;
260 7c709434 2005-03-18 devnull int n, tot, m;
262 7c709434 2005-03-18 devnull m = 128;
263 7c709434 2005-03-18 devnull buf = emalloc(m+1);
264 7c709434 2005-03-18 devnull tot = 0;
265 7c709434 2005-03-18 devnull while((n = fspread(fid, buf+tot, m-tot, tot)) > 0){
266 7c709434 2005-03-18 devnull tot += n;
267 7c709434 2005-03-18 devnull if(tot >= m){
268 7c709434 2005-03-18 devnull m += 128;
269 7c709434 2005-03-18 devnull buf = erealloc(buf, m+1);
272 7c709434 2005-03-18 devnull if(n < 0){
273 7c709434 2005-03-18 devnull free(buf);
274 7c709434 2005-03-18 devnull return nil;
276 7c709434 2005-03-18 devnull buf[tot] = 0;
277 7c709434 2005-03-18 devnull return buf;
281 7c709434 2005-03-18 devnull winmread(Win *w, char *file)
283 7c709434 2005-03-18 devnull return fsreadm(wfid(w, file));
287 7c709434 2005-03-18 devnull winindex(void)
289 7c709434 2005-03-18 devnull CFid *fid;
290 7c709434 2005-03-18 devnull char *s;
292 7c709434 2005-03-18 devnull mountacme();
293 5a396071 2005-03-21 devnull if((fid = fsopen(acmefs, "index", OREAD)) == nil)
294 7c709434 2005-03-18 devnull return nil;
295 7c709434 2005-03-18 devnull s = fsreadm(fid);
296 7c709434 2005-03-18 devnull fsclose(fid);
297 7c709434 2005-03-18 devnull return s;
301 7c709434 2005-03-18 devnull winseek(Win *w, char *file, int n, int off)
303 7c709434 2005-03-18 devnull return fsseek(wfid(w, file), n, off);
307 7c709434 2005-03-18 devnull winwriteevent(Win *w, Event *e)
309 7c709434 2005-03-18 devnull char buf[100];
311 7c709434 2005-03-18 devnull snprint(buf, sizeof buf, "%c%c%d %d \n", e->c1, e->c2, e->q0, e->q1);
312 7c709434 2005-03-18 devnull return fswrite(wfid(w, "event"), buf, strlen(buf));
316 7c709434 2005-03-18 devnull windel(Win *w, int sure)
318 7c709434 2005-03-18 devnull return winctl(w, sure ? "delete" : "del");
322 7c709434 2005-03-18 devnull winfd(Win *w, char *name, int mode)
324 7c709434 2005-03-18 devnull char buf[100];
326 7c709434 2005-03-18 devnull snprint(buf, sizeof buf, "acme/%d/%s", w->id, name);
327 7c709434 2005-03-18 devnull return fsopenfd(acmefs, buf, mode);
330 7c709434 2005-03-18 devnull static void
331 7c709434 2005-03-18 devnull error(Win *w, char *msg)
333 7c709434 2005-03-18 devnull if(msg == nil)
334 7c709434 2005-03-18 devnull longjmp(w->jmp, 1);
335 7c709434 2005-03-18 devnull fprint(2, "%s: win%d: %s\n", argv0, w->id, msg);
336 7c709434 2005-03-18 devnull longjmp(w->jmp, 2);
339 7c709434 2005-03-18 devnull static int
340 7c709434 2005-03-18 devnull getec(Win *w, CFid *efd)
342 7c709434 2005-03-18 devnull if(w->nbuf <= 0){
343 7c709434 2005-03-18 devnull w->nbuf = fsread(efd, w->buf, sizeof w->buf);
344 7c709434 2005-03-18 devnull if(w->nbuf <= 0)
345 7c709434 2005-03-18 devnull error(w, nil);
346 7c709434 2005-03-18 devnull w->bufp = w->buf;
348 7c709434 2005-03-18 devnull --w->nbuf;
349 7c709434 2005-03-18 devnull return *w->bufp++;
352 7c709434 2005-03-18 devnull static int
353 7c709434 2005-03-18 devnull geten(Win *w, CFid *efd)
355 7c709434 2005-03-18 devnull int n, c;
358 7c709434 2005-03-18 devnull while('0'<=(c=getec(w,efd)) && c<='9')
359 7c709434 2005-03-18 devnull n = n*10+(c-'0');
360 7c709434 2005-03-18 devnull if(c != ' ')
361 7c709434 2005-03-18 devnull error(w, "event number syntax");
362 7c709434 2005-03-18 devnull return n;
365 7c709434 2005-03-18 devnull static int
366 7c709434 2005-03-18 devnull geter(Win *w, CFid *efd, char *buf, int *nb)
371 7c709434 2005-03-18 devnull r = getec(w, efd);
372 7c709434 2005-03-18 devnull buf[0] = r;
374 7c709434 2005-03-18 devnull if(r < Runeself)
375 7c709434 2005-03-18 devnull goto Return;
376 7c709434 2005-03-18 devnull while(!fullrune(buf, n))
377 7c709434 2005-03-18 devnull buf[n++] = getec(w, efd);
378 7c709434 2005-03-18 devnull chartorune(&r, buf);
380 7c709434 2005-03-18 devnull *nb = n;
381 7c709434 2005-03-18 devnull return r;
384 7c709434 2005-03-18 devnull static void
385 7c709434 2005-03-18 devnull gete(Win *w, CFid *efd, Event *e)
387 7c709434 2005-03-18 devnull int i, nb;
389 7c709434 2005-03-18 devnull e->c1 = getec(w, efd);
390 7c709434 2005-03-18 devnull e->c2 = getec(w, efd);
391 7c709434 2005-03-18 devnull e->q0 = geten(w, efd);
392 7c709434 2005-03-18 devnull e->q1 = geten(w, efd);
393 7c709434 2005-03-18 devnull e->flag = geten(w, efd);
394 7c709434 2005-03-18 devnull e->nr = geten(w, efd);
395 7c709434 2005-03-18 devnull if(e->nr > EVENTSIZE)
396 7c709434 2005-03-18 devnull error(w, "event string too long");
397 7c709434 2005-03-18 devnull e->nb = 0;
398 7c709434 2005-03-18 devnull for(i=0; i<e->nr; i++){
399 7c709434 2005-03-18 devnull /* e->r[i] = */ geter(w, efd, e->text+e->nb, &nb);
400 7c709434 2005-03-18 devnull e->nb += nb;
402 7c709434 2005-03-18 devnull /* e->r[e->nr] = 0; */
403 7c709434 2005-03-18 devnull e->text[e->nb] = 0;
404 7c709434 2005-03-18 devnull if(getec(w, efd) != '\n')
405 7c709434 2005-03-18 devnull error(w, "event syntax 2");
409 7c709434 2005-03-18 devnull winreadevent(Win *w, Event *e)
411 7c709434 2005-03-18 devnull CFid *efd;
414 7c709434 2005-03-18 devnull if((r = setjmp(w->jmp)) != 0){
415 7c709434 2005-03-18 devnull if(r == 1)
416 7c709434 2005-03-18 devnull return 0;
417 7c709434 2005-03-18 devnull return -1;
419 7c709434 2005-03-18 devnull efd = wfid(w, "event");
420 7c709434 2005-03-18 devnull gete(w, efd, e);
421 7c709434 2005-03-18 devnull e->oq0 = e->q0;
422 7c709434 2005-03-18 devnull e->oq1 = e->q1;
424 7c709434 2005-03-18 devnull /* expansion */
425 7c709434 2005-03-18 devnull if(e->flag&2){
426 7c709434 2005-03-18 devnull gete(w, efd, &w->e2);
427 7c709434 2005-03-18 devnull if(e->q0==e->q1){
428 7c709434 2005-03-18 devnull w->e2.oq0 = e->q0;
429 7c709434 2005-03-18 devnull w->e2.oq1 = e->q1;
430 7c709434 2005-03-18 devnull w->e2.flag = e->flag;
431 7c709434 2005-03-18 devnull *e = w->e2;
435 7c709434 2005-03-18 devnull /* chorded argument */
436 7c709434 2005-03-18 devnull if(e->flag&8){
437 7c709434 2005-03-18 devnull gete(w, efd, &w->e3); /* arg */
438 7c709434 2005-03-18 devnull gete(w, efd, &w->e4); /* location */
439 7c709434 2005-03-18 devnull strcpy(e->arg, w->e3.text);
440 7c709434 2005-03-18 devnull strcpy(e->loc, w->e4.text);
443 7c709434 2005-03-18 devnull return 1;
447 7c709434 2005-03-18 devnull eventfmt(Fmt *fmt)
449 7c709434 2005-03-18 devnull Event *e;
451 7c709434 2005-03-18 devnull e = va_arg(fmt->args, Event*);
452 7c709434 2005-03-18 devnull return fmtprint(fmt, "%c%c %d %d %d %d %q", e->c1, e->c2, e->q0, e->q1, e->flag, e->nr, e->text);
456 7c709434 2005-03-18 devnull emalloc(uint n)
458 7c709434 2005-03-18 devnull void *v;
460 7c709434 2005-03-18 devnull v = mallocz(n, 1);
461 7c709434 2005-03-18 devnull if(v == nil)
462 7c709434 2005-03-18 devnull sysfatal("out of memory");
463 7c709434 2005-03-18 devnull return v;
467 7c709434 2005-03-18 devnull erealloc(void *v, uint n)
469 7c709434 2005-03-18 devnull v = realloc(v, n);
470 7c709434 2005-03-18 devnull if(v == nil)
471 7c709434 2005-03-18 devnull sysfatal("out of memory");
472 7c709434 2005-03-18 devnull return v;
476 7c709434 2005-03-18 devnull estrdup(char *s)
478 7c709434 2005-03-18 devnull if(s == nil)
479 7c709434 2005-03-18 devnull return nil;
480 7c709434 2005-03-18 devnull s = strdup(s);
481 7c709434 2005-03-18 devnull if(s == nil)
482 7c709434 2005-03-18 devnull sysfatal("out of memory");
483 7c709434 2005-03-18 devnull return s;
487 7c709434 2005-03-18 devnull evsmprint(char *s, va_list v)
489 7c709434 2005-03-18 devnull s = vsmprint(s, v);
490 7c709434 2005-03-18 devnull if(s == nil)
491 7c709434 2005-03-18 devnull sysfatal("out of memory");
492 7c709434 2005-03-18 devnull return s;
496 7c709434 2005-03-18 devnull pipewinto(Win *w, char *name, int errto, char *cmd, ...)
498 7c709434 2005-03-18 devnull va_list arg;
499 7c709434 2005-03-18 devnull char *p;
500 7c709434 2005-03-18 devnull int fd[3], pid;
502 7c709434 2005-03-18 devnull va_start(arg, cmd);
503 7c709434 2005-03-18 devnull p = evsmprint(cmd, arg);
504 7c709434 2005-03-18 devnull va_end(arg);
505 7c709434 2005-03-18 devnull fd[0] = winfd(w, name, OREAD);
506 7c709434 2005-03-18 devnull fd[1] = dup(errto, -1);
507 7c709434 2005-03-18 devnull fd[2] = dup(errto, -1);
508 7c709434 2005-03-18 devnull pid = threadspawnl(fd, "rc", "rc", "-c", p, 0);
509 7c709434 2005-03-18 devnull free(p);
510 7c709434 2005-03-18 devnull return pid;
514 7c709434 2005-03-18 devnull pipetowin(Win *w, char *name, int errto, char *cmd, ...)
516 7c709434 2005-03-18 devnull va_list arg;
517 7c709434 2005-03-18 devnull char *p;
518 7c709434 2005-03-18 devnull int fd[3], pid, pfd[2];
519 7c709434 2005-03-18 devnull char buf[1024];
523 7c709434 2005-03-18 devnull * cannot use winfd here because of buffering caused
524 7c709434 2005-03-18 devnull * by pipe. program might exit before final write to acme
525 7c709434 2005-03-18 devnull * happens. so we might return before the final write.
527 7c709434 2005-03-18 devnull * to avoid this, we tend the pipe ourselves.
529 7c709434 2005-03-18 devnull if(pipe(pfd) < 0)
530 7c709434 2005-03-18 devnull sysfatal("pipe: %r");
531 7c709434 2005-03-18 devnull va_start(arg, cmd);
532 7c709434 2005-03-18 devnull p = evsmprint(cmd, arg);
533 7c709434 2005-03-18 devnull va_end(arg);
534 7c709434 2005-03-18 devnull fd[0] = open("/dev/null", OREAD);
535 7c709434 2005-03-18 devnull fd[1] = pfd[1];
536 7c709434 2005-03-18 devnull if(errto == 0)
537 7c709434 2005-03-18 devnull fd[2] = dup(fd[1], -1);
539 7c709434 2005-03-18 devnull fd[2] = dup(errto, -1);
540 7c709434 2005-03-18 devnull pid = threadspawnl(fd, "rc", "rc", "-c", p, 0);
541 7c709434 2005-03-18 devnull free(p);
542 7c709434 2005-03-18 devnull while((n = read(pfd[0], buf, sizeof buf)) > 0)
543 7c709434 2005-03-18 devnull winwrite(w, name, buf, n);
544 7c709434 2005-03-18 devnull close(pfd[0]);
545 7c709434 2005-03-18 devnull return pid;
549 7c709434 2005-03-18 devnull sysrun(int errto, char *fmt, ...)
551 7c709434 2005-03-18 devnull static char buf[1024];
552 7c709434 2005-03-18 devnull char *cmd;
553 7c709434 2005-03-18 devnull va_list arg;
554 7c709434 2005-03-18 devnull int n, fd[3], p[2], tot, pid;
556 7c709434 2005-03-18 devnull #undef pipe
557 7c709434 2005-03-18 devnull if(pipe(p) < 0)
558 7c709434 2005-03-18 devnull sysfatal("pipe: %r");
559 7c709434 2005-03-18 devnull fd[0] = open("/dev/null", OREAD);
560 7c709434 2005-03-18 devnull fd[1] = p[1];
561 7c709434 2005-03-18 devnull if(errto == 0)
562 7c709434 2005-03-18 devnull fd[2] = dup(fd[1], -1);
564 7c709434 2005-03-18 devnull fd[2] = dup(errto, -1);
566 7c709434 2005-03-18 devnull va_start(arg, fmt);
567 7c709434 2005-03-18 devnull cmd = evsmprint(fmt, arg);
568 7c709434 2005-03-18 devnull va_end(arg);
569 7c709434 2005-03-18 devnull pid = threadspawnl(fd, "rc", "rc", "-c", cmd, 0);
571 7c709434 2005-03-18 devnull tot = 0;
572 7c709434 2005-03-18 devnull while((n = read(p[0], buf+tot, sizeof buf-tot)) > 0)
573 7c709434 2005-03-18 devnull tot += n;
574 7c709434 2005-03-18 devnull close(p[0]);
575 7c709434 2005-03-18 devnull twait(pid);
576 7c709434 2005-03-18 devnull if(n < 0)
577 7c709434 2005-03-18 devnull return nil;
578 7c709434 2005-03-18 devnull free(cmd);
579 7c709434 2005-03-18 devnull if(tot == sizeof buf)
581 7c709434 2005-03-18 devnull buf[tot] = 0;
582 3bd56b04 2005-09-09 devnull while(tot > 0 && isspace((uchar)buf[tot-1]))
584 7c709434 2005-03-18 devnull buf[tot] = 0;
585 7c709434 2005-03-18 devnull if(tot == 0){
586 7c709434 2005-03-18 devnull werrstr("no output");
587 7c709434 2005-03-18 devnull return nil;
589 7c709434 2005-03-18 devnull return estrdup(buf);
592 7c709434 2005-03-18 devnull static void
593 7c709434 2005-03-18 devnull eventreader(void *v)
595 7c709434 2005-03-18 devnull Event e[2];
601 7c709434 2005-03-18 devnull for(;;){
602 7c709434 2005-03-18 devnull if(winreadevent(w, &e[i]) <= 0)
604 7c709434 2005-03-18 devnull sendp(w->c, &e[i]);
605 7c709434 2005-03-18 devnull i = 1-i; /* toggle */
607 7c709434 2005-03-18 devnull sendp(w->c, nil);
608 7c709434 2005-03-18 devnull threadexits(nil);
611 7c709434 2005-03-18 devnull Channel*
612 7c709434 2005-03-18 devnull wineventchan(Win *w)
614 7c709434 2005-03-18 devnull if(w->c == nil){
615 7c709434 2005-03-18 devnull w->c = chancreate(sizeof(Event*), 0);
616 7c709434 2005-03-18 devnull threadcreate(eventreader, w, 32*1024);
618 7c709434 2005-03-18 devnull return w->c;
622 7c709434 2005-03-18 devnull wingetname(Win *w)
625 7c709434 2005-03-18 devnull char *p;
627 7c709434 2005-03-18 devnull n = winread(w, "tag", w->name, sizeof w->name-1);
628 7c709434 2005-03-18 devnull if(n <= 0)
629 7c709434 2005-03-18 devnull return nil;
630 7c709434 2005-03-18 devnull w->name[n] = 0;
631 7c709434 2005-03-18 devnull p = strchr(w->name, ' ');
634 7c709434 2005-03-18 devnull return w->name;