Blame


1 8ad51794 2004-03-25 devnull #include <u.h>
2 8ad51794 2004-03-25 devnull #include <libc.h>
3 8ad51794 2004-03-25 devnull #include <thread.h>
4 8ad51794 2004-03-25 devnull #include <fcall.h>
5 452c0935 2005-01-04 devnull #include <9pclient.h>
6 8ad51794 2004-03-25 devnull #include "term.h"
7 b4a659b6 2004-04-19 devnull
8 b4a659b6 2004-04-19 devnull int noecho = 1;
9 8ad51794 2004-03-25 devnull
10 8ad51794 2004-03-25 devnull #define EVENTSIZE 256
11 8ad51794 2004-03-25 devnull #define STACK 32768
12 8ad51794 2004-03-25 devnull
13 8ad51794 2004-03-25 devnull typedef struct Event Event;
14 8ad51794 2004-03-25 devnull typedef struct Q Q;
15 8ad51794 2004-03-25 devnull
16 8ad51794 2004-03-25 devnull struct Event
17 8ad51794 2004-03-25 devnull {
18 8ad51794 2004-03-25 devnull int c1;
19 8ad51794 2004-03-25 devnull int c2;
20 8ad51794 2004-03-25 devnull int q0;
21 8ad51794 2004-03-25 devnull int q1;
22 8ad51794 2004-03-25 devnull int flag;
23 8ad51794 2004-03-25 devnull int nb;
24 8ad51794 2004-03-25 devnull int nr;
25 8ad51794 2004-03-25 devnull char b[EVENTSIZE*UTFmax+1];
26 8ad51794 2004-03-25 devnull Rune r[EVENTSIZE+1];
27 8ad51794 2004-03-25 devnull };
28 8ad51794 2004-03-25 devnull
29 8ad51794 2004-03-25 devnull Event blank = {
30 8ad51794 2004-03-25 devnull 'M',
31 8ad51794 2004-03-25 devnull 'X',
32 8ad51794 2004-03-25 devnull 0, 0, 0, 1, 1,
33 8ad51794 2004-03-25 devnull { ' ', 0 },
34 8ad51794 2004-03-25 devnull { ' ', 0 },
35 8ad51794 2004-03-25 devnull };
36 8ad51794 2004-03-25 devnull
37 8ad51794 2004-03-25 devnull struct Q
38 8ad51794 2004-03-25 devnull {
39 8ad51794 2004-03-25 devnull QLock lk;
40 8ad51794 2004-03-25 devnull int p;
41 8ad51794 2004-03-25 devnull int k;
42 8ad51794 2004-03-25 devnull };
43 8ad51794 2004-03-25 devnull
44 8ad51794 2004-03-25 devnull Q q;
45 8ad51794 2004-03-25 devnull
46 452c0935 2005-01-04 devnull CFid *eventfd;
47 452c0935 2005-01-04 devnull CFid *addrfd;
48 452c0935 2005-01-04 devnull CFid *datafd;
49 452c0935 2005-01-04 devnull CFid *ctlfd;
50 8ad51794 2004-03-25 devnull // int bodyfd;
51 8ad51794 2004-03-25 devnull
52 8ad51794 2004-03-25 devnull char *typing;
53 8ad51794 2004-03-25 devnull int ntypeb;
54 8ad51794 2004-03-25 devnull int ntyper;
55 8ad51794 2004-03-25 devnull int ntypebreak;
56 8ad51794 2004-03-25 devnull int debug;
57 8ad51794 2004-03-25 devnull int rcfd;
58 8ad51794 2004-03-25 devnull
59 8ad51794 2004-03-25 devnull char *name;
60 8ad51794 2004-03-25 devnull
61 8ad51794 2004-03-25 devnull char **prog;
62 8ad51794 2004-03-25 devnull Channel *cwait;
63 8ad51794 2004-03-25 devnull int pid = -1;
64 8ad51794 2004-03-25 devnull
65 8ad51794 2004-03-25 devnull int label(char*, int);
66 4b970769 2005-03-05 devnull void error(char*, ...);
67 8ad51794 2004-03-25 devnull void stdinproc(void*);
68 8ad51794 2004-03-25 devnull void stdoutproc(void*);
69 452c0935 2005-01-04 devnull void type(Event*, int, CFid*, CFid*);
70 452c0935 2005-01-04 devnull void sende(Event*, int, CFid*, CFid*, CFid*, int);
71 8ad51794 2004-03-25 devnull char *onestring(int, char**);
72 8ad51794 2004-03-25 devnull int delete(Event*);
73 8ad51794 2004-03-25 devnull void deltype(uint, uint);
74 8ad51794 2004-03-25 devnull void runproc(void*);
75 8ad51794 2004-03-25 devnull
76 8ad51794 2004-03-25 devnull int
77 452c0935 2005-01-04 devnull fsfidprint(CFid *fid, char *fmt, ...)
78 8ad51794 2004-03-25 devnull {
79 8ad51794 2004-03-25 devnull char buf[256];
80 8ad51794 2004-03-25 devnull va_list arg;
81 8ad51794 2004-03-25 devnull int n;
82 8ad51794 2004-03-25 devnull
83 8ad51794 2004-03-25 devnull va_start(arg, fmt);
84 8ad51794 2004-03-25 devnull n = vsnprint(buf, sizeof buf, fmt, arg);
85 8ad51794 2004-03-25 devnull va_end(arg);
86 8ad51794 2004-03-25 devnull return fswrite(fid, buf, n);
87 8ad51794 2004-03-25 devnull }
88 8ad51794 2004-03-25 devnull
89 8ad51794 2004-03-25 devnull void
90 8ad51794 2004-03-25 devnull usage(void)
91 8ad51794 2004-03-25 devnull {
92 8ad51794 2004-03-25 devnull fprint(2, "usage: win cmd args...\n");
93 8ad51794 2004-03-25 devnull threadexitsall("usage");
94 8ad51794 2004-03-25 devnull }
95 8ad51794 2004-03-25 devnull
96 8ad51794 2004-03-25 devnull int
97 8ad51794 2004-03-25 devnull nopipes(void *v, char *msg)
98 8ad51794 2004-03-25 devnull {
99 8ad51794 2004-03-25 devnull USED(v);
100 8ad51794 2004-03-25 devnull if(strcmp(msg, "sys: write on closed pipe") == 0)
101 8ad51794 2004-03-25 devnull return 1;
102 8ad51794 2004-03-25 devnull return 0;
103 8ad51794 2004-03-25 devnull }
104 8ad51794 2004-03-25 devnull
105 8ad51794 2004-03-25 devnull void
106 8ad51794 2004-03-25 devnull waitthread(void *v)
107 8ad51794 2004-03-25 devnull {
108 8ad51794 2004-03-25 devnull recvp(cwait);
109 8ad51794 2004-03-25 devnull threadexitsall(nil);
110 60535a5f 2004-12-26 devnull }
111 60535a5f 2004-12-26 devnull
112 60535a5f 2004-12-26 devnull void
113 60535a5f 2004-12-26 devnull hangupnote(void *a, char *msg)
114 60535a5f 2004-12-26 devnull {
115 60535a5f 2004-12-26 devnull if(strcmp(msg, "hangup") == 0 && pid != 0){
116 60535a5f 2004-12-26 devnull postnote(PNGROUP, pid, "hangup");
117 60535a5f 2004-12-26 devnull noted(NDFLT);
118 60535a5f 2004-12-26 devnull }
119 60535a5f 2004-12-26 devnull if(strstr(msg, "child")){
120 60535a5f 2004-12-26 devnull /* bug: do better */
121 60535a5f 2004-12-26 devnull threadexitsall(0);
122 60535a5f 2004-12-26 devnull }
123 60535a5f 2004-12-26 devnull noted(NDFLT);
124 8ad51794 2004-03-25 devnull }
125 8ad51794 2004-03-25 devnull
126 8ad51794 2004-03-25 devnull void
127 8ad51794 2004-03-25 devnull threadmain(int argc, char **argv)
128 8ad51794 2004-03-25 devnull {
129 8ad51794 2004-03-25 devnull int fd, id;
130 8ad51794 2004-03-25 devnull char buf[256];
131 8ad51794 2004-03-25 devnull char buf1[128];
132 452c0935 2005-01-04 devnull CFsys *fs;
133 8ad51794 2004-03-25 devnull
134 8ad51794 2004-03-25 devnull ARGBEGIN{
135 8ad51794 2004-03-25 devnull case 'd':
136 8ad51794 2004-03-25 devnull debug = 1;
137 8ad51794 2004-03-25 devnull break;
138 b1455f33 2004-04-30 devnull case 'n':
139 b1455f33 2004-04-30 devnull name = EARGF(usage());
140 b1455f33 2004-04-30 devnull break;
141 8ad51794 2004-03-25 devnull default:
142 8ad51794 2004-03-25 devnull usage();
143 8ad51794 2004-03-25 devnull }ARGEND
144 8ad51794 2004-03-25 devnull
145 8ad51794 2004-03-25 devnull prog = argv;
146 8ad51794 2004-03-25 devnull
147 b1455f33 2004-04-30 devnull if(name == nil){
148 b1455f33 2004-04-30 devnull if(argc > 0)
149 b1455f33 2004-04-30 devnull name = argv[0];
150 b1455f33 2004-04-30 devnull else{
151 b1455f33 2004-04-30 devnull name = sysname();
152 b1455f33 2004-04-30 devnull if(name == nil)
153 b1455f33 2004-04-30 devnull name = "gnot";
154 b1455f33 2004-04-30 devnull }
155 b1455f33 2004-04-30 devnull }
156 8ad51794 2004-03-25 devnull
157 60535a5f 2004-12-26 devnull notedisable("sys: write on closed pipe");
158 60535a5f 2004-12-26 devnull noteenable("sys: child");
159 60535a5f 2004-12-26 devnull notify(hangupnote);
160 60535a5f 2004-12-26 devnull
161 be22ae2d 2004-03-26 devnull if((fs = nsmount("acme", "")) == 0)
162 8ad51794 2004-03-25 devnull sysfatal("nsmount acme: %r");
163 8ad51794 2004-03-25 devnull ctlfd = fsopen(fs, "new/ctl", ORDWR|OCEXEC);
164 be22ae2d 2004-03-26 devnull if(ctlfd == 0 || fsread(ctlfd, buf, 12) != 12)
165 8ad51794 2004-03-25 devnull sysfatal("ctl: %r");
166 8ad51794 2004-03-25 devnull id = atoi(buf);
167 2d930d45 2004-04-25 devnull snprint(buf, sizeof buf, "%d", id);
168 2d930d45 2004-04-25 devnull putenv("winid", buf);
169 8ad51794 2004-03-25 devnull sprint(buf, "%d/tag", id);
170 8ad51794 2004-03-25 devnull fd = fsopenfd(fs, buf, OWRITE|OCEXEC);
171 8ad51794 2004-03-25 devnull write(fd, " Send Delete", 12);
172 8ad51794 2004-03-25 devnull close(fd);
173 8ad51794 2004-03-25 devnull sprint(buf, "%d/event", id);
174 8ad51794 2004-03-25 devnull eventfd = fsopen(fs, buf, ORDWR|OCEXEC);
175 8ad51794 2004-03-25 devnull sprint(buf, "%d/addr", id);
176 8ad51794 2004-03-25 devnull addrfd = fsopen(fs, buf, ORDWR|OCEXEC);
177 8ad51794 2004-03-25 devnull sprint(buf, "%d/data", id);
178 8ad51794 2004-03-25 devnull datafd = fsopen(fs, buf, ORDWR|OCEXEC);
179 8ad51794 2004-03-25 devnull sprint(buf, "%d/body", id);
180 8ad51794 2004-03-25 devnull /* bodyfd = fsopenfd(fs, buf, ORDWR|OCEXEC); */
181 8ad51794 2004-03-25 devnull if(eventfd==nil || addrfd==nil || datafd==nil)
182 8ad51794 2004-03-25 devnull sysfatal("data files: %r");
183 8ad51794 2004-03-25 devnull /*
184 8ad51794 2004-03-25 devnull if(eventfd<0 || addrfd<0 || datafd<0 || bodyfd<0)
185 8ad51794 2004-03-25 devnull sysfatal("data files: %r");
186 8ad51794 2004-03-25 devnull */
187 8ad51794 2004-03-25 devnull fsunmount(fs);
188 8ad51794 2004-03-25 devnull
189 8ad51794 2004-03-25 devnull cwait = threadwaitchan();
190 8ad51794 2004-03-25 devnull threadcreate(waitthread, nil, STACK);
191 4dcd9af2 2004-04-15 devnull pid = rcstart(argc, argv, &rcfd, nil);
192 8ad51794 2004-03-25 devnull if(pid == -1)
193 8ad51794 2004-03-25 devnull sysfatal("exec failed");
194 8ad51794 2004-03-25 devnull
195 8ad51794 2004-03-25 devnull getwd(buf1, sizeof buf1);
196 8ad51794 2004-03-25 devnull sprint(buf, "name %s/-%s\n0\n", buf1, name);
197 8ad51794 2004-03-25 devnull fswrite(ctlfd, buf, strlen(buf));
198 8ad51794 2004-03-25 devnull sprint(buf, "dumpdir %s/\n", buf1);
199 8ad51794 2004-03-25 devnull fswrite(ctlfd, buf, strlen(buf));
200 8ad51794 2004-03-25 devnull sprint(buf, "dump %s\n", onestring(argc, argv));
201 8ad51794 2004-03-25 devnull fswrite(ctlfd, buf, strlen(buf));
202 8ad51794 2004-03-25 devnull
203 5e0f7e8a 2004-04-23 devnull updatewinsize(25, 80, 0, 0);
204 60535a5f 2004-12-26 devnull proccreate(stdoutproc, nil, STACK);
205 8ad51794 2004-03-25 devnull stdinproc(nil);
206 8ad51794 2004-03-25 devnull }
207 8ad51794 2004-03-25 devnull
208 8ad51794 2004-03-25 devnull void
209 4b970769 2005-03-05 devnull error(char *s, ...)
210 8ad51794 2004-03-25 devnull {
211 4b970769 2005-03-05 devnull va_list arg;
212 4b970769 2005-03-05 devnull
213 4b970769 2005-03-05 devnull if(s){
214 4b970769 2005-03-05 devnull va_start(arg, s);
215 4b970769 2005-03-05 devnull s = vsmprint(s, arg);
216 4b970769 2005-03-05 devnull va_end(arg);
217 4b970769 2005-03-05 devnull }
218 8ad51794 2004-03-25 devnull if(s)
219 8ad51794 2004-03-25 devnull fprint(2, "win: %s: %r\n", s);
220 8ad51794 2004-03-25 devnull else
221 8ad51794 2004-03-25 devnull s = "kill";
222 8ad51794 2004-03-25 devnull if(pid != -1)
223 8ad51794 2004-03-25 devnull postnote(PNGROUP, pid, "hangup");
224 8ad51794 2004-03-25 devnull threadexitsall(s);
225 8ad51794 2004-03-25 devnull }
226 8ad51794 2004-03-25 devnull
227 8ad51794 2004-03-25 devnull char*
228 8ad51794 2004-03-25 devnull onestring(int argc, char **argv)
229 8ad51794 2004-03-25 devnull {
230 8ad51794 2004-03-25 devnull char *p;
231 8ad51794 2004-03-25 devnull int i, n;
232 8ad51794 2004-03-25 devnull static char buf[1024];
233 8ad51794 2004-03-25 devnull
234 8ad51794 2004-03-25 devnull if(argc == 0)
235 8ad51794 2004-03-25 devnull return "";
236 8ad51794 2004-03-25 devnull p = buf;
237 8ad51794 2004-03-25 devnull for(i=0; i<argc; i++){
238 8ad51794 2004-03-25 devnull n = strlen(argv[i]);
239 8ad51794 2004-03-25 devnull if(p+n+1 >= buf+sizeof buf)
240 8ad51794 2004-03-25 devnull break;
241 8ad51794 2004-03-25 devnull memmove(p, argv[i], n);
242 8ad51794 2004-03-25 devnull p += n;
243 8ad51794 2004-03-25 devnull *p++ = ' ';
244 8ad51794 2004-03-25 devnull }
245 8ad51794 2004-03-25 devnull p[-1] = 0;
246 8ad51794 2004-03-25 devnull return buf;
247 8ad51794 2004-03-25 devnull }
248 8ad51794 2004-03-25 devnull
249 8ad51794 2004-03-25 devnull int
250 452c0935 2005-01-04 devnull getec(CFid *efd)
251 8ad51794 2004-03-25 devnull {
252 8ad51794 2004-03-25 devnull static char buf[8192];
253 8ad51794 2004-03-25 devnull static char *bufp;
254 8ad51794 2004-03-25 devnull static int nbuf;
255 8ad51794 2004-03-25 devnull
256 8ad51794 2004-03-25 devnull if(nbuf == 0){
257 8ad51794 2004-03-25 devnull nbuf = fsread(efd, buf, sizeof buf);
258 8ad51794 2004-03-25 devnull if(nbuf <= 0)
259 8ad51794 2004-03-25 devnull error(nil);
260 8ad51794 2004-03-25 devnull bufp = buf;
261 8ad51794 2004-03-25 devnull }
262 8ad51794 2004-03-25 devnull --nbuf;
263 8ad51794 2004-03-25 devnull return *bufp++;
264 8ad51794 2004-03-25 devnull }
265 8ad51794 2004-03-25 devnull
266 8ad51794 2004-03-25 devnull int
267 452c0935 2005-01-04 devnull geten(CFid *efd)
268 8ad51794 2004-03-25 devnull {
269 8ad51794 2004-03-25 devnull int n, c;
270 8ad51794 2004-03-25 devnull
271 8ad51794 2004-03-25 devnull n = 0;
272 8ad51794 2004-03-25 devnull while('0'<=(c=getec(efd)) && c<='9')
273 8ad51794 2004-03-25 devnull n = n*10+(c-'0');
274 8ad51794 2004-03-25 devnull if(c != ' ')
275 8ad51794 2004-03-25 devnull error("event number syntax");
276 8ad51794 2004-03-25 devnull return n;
277 8ad51794 2004-03-25 devnull }
278 8ad51794 2004-03-25 devnull
279 8ad51794 2004-03-25 devnull int
280 452c0935 2005-01-04 devnull geter(CFid *efd, char *buf, int *nb)
281 8ad51794 2004-03-25 devnull {
282 8ad51794 2004-03-25 devnull Rune r;
283 8ad51794 2004-03-25 devnull int n;
284 8ad51794 2004-03-25 devnull
285 8ad51794 2004-03-25 devnull r = getec(efd);
286 8ad51794 2004-03-25 devnull buf[0] = r;
287 8ad51794 2004-03-25 devnull n = 1;
288 8ad51794 2004-03-25 devnull if(r < Runeself)
289 8ad51794 2004-03-25 devnull goto Return;
290 8ad51794 2004-03-25 devnull while(!fullrune(buf, n))
291 8ad51794 2004-03-25 devnull buf[n++] = getec(efd);
292 8ad51794 2004-03-25 devnull chartorune(&r, buf);
293 8ad51794 2004-03-25 devnull Return:
294 8ad51794 2004-03-25 devnull *nb = n;
295 8ad51794 2004-03-25 devnull return r;
296 8ad51794 2004-03-25 devnull }
297 8ad51794 2004-03-25 devnull
298 8ad51794 2004-03-25 devnull void
299 452c0935 2005-01-04 devnull gete(CFid *efd, Event *e)
300 8ad51794 2004-03-25 devnull {
301 8ad51794 2004-03-25 devnull int i, nb;
302 8ad51794 2004-03-25 devnull
303 8ad51794 2004-03-25 devnull e->c1 = getec(efd);
304 8ad51794 2004-03-25 devnull e->c2 = getec(efd);
305 8ad51794 2004-03-25 devnull e->q0 = geten(efd);
306 8ad51794 2004-03-25 devnull e->q1 = geten(efd);
307 8ad51794 2004-03-25 devnull e->flag = geten(efd);
308 8ad51794 2004-03-25 devnull e->nr = geten(efd);
309 8ad51794 2004-03-25 devnull if(e->nr > EVENTSIZE)
310 8ad51794 2004-03-25 devnull error("event string too long");
311 8ad51794 2004-03-25 devnull e->nb = 0;
312 8ad51794 2004-03-25 devnull for(i=0; i<e->nr; i++){
313 8ad51794 2004-03-25 devnull e->r[i] = geter(efd, e->b+e->nb, &nb);
314 8ad51794 2004-03-25 devnull e->nb += nb;
315 8ad51794 2004-03-25 devnull }
316 8ad51794 2004-03-25 devnull e->r[e->nr] = 0;
317 8ad51794 2004-03-25 devnull e->b[e->nb] = 0;
318 8ad51794 2004-03-25 devnull if(getec(efd) != '\n')
319 8ad51794 2004-03-25 devnull error("event syntax 2");
320 8ad51794 2004-03-25 devnull }
321 8ad51794 2004-03-25 devnull
322 8ad51794 2004-03-25 devnull int
323 8ad51794 2004-03-25 devnull nrunes(char *s, int nb)
324 8ad51794 2004-03-25 devnull {
325 8ad51794 2004-03-25 devnull int i, n;
326 8ad51794 2004-03-25 devnull Rune r;
327 8ad51794 2004-03-25 devnull
328 8ad51794 2004-03-25 devnull n = 0;
329 8ad51794 2004-03-25 devnull for(i=0; i<nb; n++)
330 8ad51794 2004-03-25 devnull i += chartorune(&r, s+i);
331 8ad51794 2004-03-25 devnull return n;
332 8ad51794 2004-03-25 devnull }
333 8ad51794 2004-03-25 devnull
334 8ad51794 2004-03-25 devnull void
335 8ad51794 2004-03-25 devnull stdinproc(void *v)
336 8ad51794 2004-03-25 devnull {
337 452c0935 2005-01-04 devnull CFid *cfd = ctlfd;
338 452c0935 2005-01-04 devnull CFid *efd = eventfd;
339 452c0935 2005-01-04 devnull CFid *dfd = datafd;
340 452c0935 2005-01-04 devnull CFid *afd = addrfd;
341 8ad51794 2004-03-25 devnull int fd0 = rcfd;
342 8ad51794 2004-03-25 devnull Event e, e2, e3, e4;
343 8ad51794 2004-03-25 devnull
344 8ad51794 2004-03-25 devnull USED(v);
345 8ad51794 2004-03-25 devnull
346 8ad51794 2004-03-25 devnull for(;;){
347 8ad51794 2004-03-25 devnull if(debug)
348 8ad51794 2004-03-25 devnull fprint(2, "typing[%d,%d)\n", q.p, q.p+ntyper);
349 8ad51794 2004-03-25 devnull gete(efd, &e);
350 8ad51794 2004-03-25 devnull if(debug)
351 8ad51794 2004-03-25 devnull fprint(2, "msg %c%c q[%d,%d)... ", e.c1, e.c2, e.q0, e.q1);
352 8ad51794 2004-03-25 devnull qlock(&q.lk);
353 8ad51794 2004-03-25 devnull switch(e.c1){
354 8ad51794 2004-03-25 devnull default:
355 8ad51794 2004-03-25 devnull Unknown:
356 8ad51794 2004-03-25 devnull print("unknown message %c%c\n", e.c1, e.c2);
357 8ad51794 2004-03-25 devnull break;
358 8ad51794 2004-03-25 devnull
359 8ad51794 2004-03-25 devnull case 'E': /* write to body; can't affect us */
360 8ad51794 2004-03-25 devnull if(debug)
361 8ad51794 2004-03-25 devnull fprint(2, "shift typing %d... ", e.q1-e.q0);
362 8ad51794 2004-03-25 devnull q.p += e.q1-e.q0;
363 8ad51794 2004-03-25 devnull break;
364 8ad51794 2004-03-25 devnull
365 8ad51794 2004-03-25 devnull case 'F': /* generated by our actions; ignore */
366 8ad51794 2004-03-25 devnull break;
367 8ad51794 2004-03-25 devnull
368 8ad51794 2004-03-25 devnull case 'K':
369 8ad51794 2004-03-25 devnull case 'M':
370 8ad51794 2004-03-25 devnull switch(e.c2){
371 8ad51794 2004-03-25 devnull case 'I':
372 8ad51794 2004-03-25 devnull if(e.q0 < q.p){
373 8ad51794 2004-03-25 devnull if(debug)
374 8ad51794 2004-03-25 devnull fprint(2, "shift typing %d... ", e.q1-e.q0);
375 8ad51794 2004-03-25 devnull q.p += e.q1-e.q0;
376 8ad51794 2004-03-25 devnull }
377 8ad51794 2004-03-25 devnull else if(e.q0 <= q.p+ntyper){
378 8ad51794 2004-03-25 devnull if(debug)
379 8ad51794 2004-03-25 devnull fprint(2, "type... ");
380 8ad51794 2004-03-25 devnull type(&e, fd0, afd, dfd);
381 8ad51794 2004-03-25 devnull }
382 8ad51794 2004-03-25 devnull break;
383 8ad51794 2004-03-25 devnull
384 8ad51794 2004-03-25 devnull case 'D':
385 8ad51794 2004-03-25 devnull q.p -= delete(&e);
386 8ad51794 2004-03-25 devnull break;
387 8ad51794 2004-03-25 devnull
388 8ad51794 2004-03-25 devnull case 'x':
389 8ad51794 2004-03-25 devnull case 'X':
390 8ad51794 2004-03-25 devnull if(e.flag & 2)
391 8ad51794 2004-03-25 devnull gete(efd, &e2);
392 8ad51794 2004-03-25 devnull if(e.flag & 8){
393 8ad51794 2004-03-25 devnull gete(efd, &e3);
394 8ad51794 2004-03-25 devnull gete(efd, &e4);
395 8ad51794 2004-03-25 devnull }
396 8ad51794 2004-03-25 devnull if(e.flag&1 || (e.c2=='x' && e.nr==0 && e2.nr==0)){
397 8ad51794 2004-03-25 devnull /* send it straight back */
398 8ad51794 2004-03-25 devnull fsfidprint(efd, "%c%c%d %d\n", e.c1, e.c2, e.q0, e.q1);
399 8ad51794 2004-03-25 devnull break;
400 8ad51794 2004-03-25 devnull }
401 8ad51794 2004-03-25 devnull if(e.q0==e.q1 && (e.flag&2)){
402 8ad51794 2004-03-25 devnull e2.flag = e.flag;
403 8ad51794 2004-03-25 devnull e = e2;
404 8ad51794 2004-03-25 devnull }
405 8ad51794 2004-03-25 devnull if(e.flag & 8){
406 8ad51794 2004-03-25 devnull if(e.q1 != e.q0){
407 8ad51794 2004-03-25 devnull sende(&e, fd0, cfd, afd, dfd, 0);
408 8ad51794 2004-03-25 devnull sende(&blank, fd0, cfd, afd, dfd, 0);
409 8ad51794 2004-03-25 devnull }
410 8ad51794 2004-03-25 devnull sende(&e3, fd0, cfd, afd, dfd, 1);
411 8ad51794 2004-03-25 devnull }else if(e.q1 != e.q0)
412 8ad51794 2004-03-25 devnull sende(&e, fd0, cfd, afd, dfd, 1);
413 8ad51794 2004-03-25 devnull break;
414 8ad51794 2004-03-25 devnull
415 8ad51794 2004-03-25 devnull case 'l':
416 8ad51794 2004-03-25 devnull case 'L':
417 8ad51794 2004-03-25 devnull /* just send it back */
418 8ad51794 2004-03-25 devnull if(e.flag & 2)
419 8ad51794 2004-03-25 devnull gete(efd, &e2);
420 8ad51794 2004-03-25 devnull fsfidprint(efd, "%c%c%d %d\n", e.c1, e.c2, e.q0, e.q1);
421 8ad51794 2004-03-25 devnull break;
422 8ad51794 2004-03-25 devnull
423 8ad51794 2004-03-25 devnull case 'd':
424 8ad51794 2004-03-25 devnull case 'i':
425 8ad51794 2004-03-25 devnull break;
426 8ad51794 2004-03-25 devnull
427 8ad51794 2004-03-25 devnull default:
428 8ad51794 2004-03-25 devnull goto Unknown;
429 8ad51794 2004-03-25 devnull }
430 8ad51794 2004-03-25 devnull }
431 8ad51794 2004-03-25 devnull qunlock(&q.lk);
432 8ad51794 2004-03-25 devnull }
433 8ad51794 2004-03-25 devnull }
434 8ad51794 2004-03-25 devnull
435 8ad51794 2004-03-25 devnull void
436 8ad51794 2004-03-25 devnull stdoutproc(void *v)
437 8ad51794 2004-03-25 devnull {
438 8ad51794 2004-03-25 devnull int fd1 = rcfd;
439 452c0935 2005-01-04 devnull CFid *afd = addrfd;
440 452c0935 2005-01-04 devnull CFid *dfd = datafd;
441 8ad51794 2004-03-25 devnull int n, m, w, npart;
442 8ad51794 2004-03-25 devnull char *buf, *s, *t;
443 8ad51794 2004-03-25 devnull Rune r;
444 8ad51794 2004-03-25 devnull char x[16], hold[UTFmax];
445 8ad51794 2004-03-25 devnull
446 8ad51794 2004-03-25 devnull USED(v);
447 8ad51794 2004-03-25 devnull buf = malloc(8192+UTFmax+1);
448 8ad51794 2004-03-25 devnull npart = 0;
449 8ad51794 2004-03-25 devnull for(;;){
450 8ad51794 2004-03-25 devnull /* Let typing have a go -- maybe there's a rubout waiting. */
451 8ad51794 2004-03-25 devnull yield();
452 60535a5f 2004-12-26 devnull n = read(fd1, buf+npart, 8192);
453 f8104b3d 2005-01-05 devnull if(n <= 0)
454 8ad51794 2004-03-25 devnull error(nil);
455 8ad51794 2004-03-25 devnull
456 8ad51794 2004-03-25 devnull /* squash NULs */
457 8ad51794 2004-03-25 devnull s = memchr(buf+npart, 0, n);
458 8ad51794 2004-03-25 devnull if(s){
459 8ad51794 2004-03-25 devnull for(t=s; s<buf+npart+n; s++)
460 8ad51794 2004-03-25 devnull if(*t = *s) /* assign = */
461 8ad51794 2004-03-25 devnull t++;
462 8ad51794 2004-03-25 devnull n = t-(buf+npart);
463 8ad51794 2004-03-25 devnull }
464 8ad51794 2004-03-25 devnull
465 8ad51794 2004-03-25 devnull n += npart;
466 8ad51794 2004-03-25 devnull
467 8ad51794 2004-03-25 devnull /* hold on to final partial rune */
468 8ad51794 2004-03-25 devnull npart = 0;
469 8ad51794 2004-03-25 devnull while(n>0 && (buf[n-1]&0xC0)){
470 8ad51794 2004-03-25 devnull --n;
471 8ad51794 2004-03-25 devnull npart++;
472 8ad51794 2004-03-25 devnull if((buf[n]&0xC0)!=0x80){
473 8ad51794 2004-03-25 devnull if(fullrune(buf+n, npart)){
474 8ad51794 2004-03-25 devnull w = chartorune(&r, buf+n);
475 8ad51794 2004-03-25 devnull n += w;
476 8ad51794 2004-03-25 devnull npart -= w;
477 8ad51794 2004-03-25 devnull }
478 8ad51794 2004-03-25 devnull break;
479 8ad51794 2004-03-25 devnull }
480 8ad51794 2004-03-25 devnull }
481 8ad51794 2004-03-25 devnull if(n > 0){
482 8ad51794 2004-03-25 devnull memmove(hold, buf+n, npart);
483 8ad51794 2004-03-25 devnull buf[n] = 0;
484 8ad51794 2004-03-25 devnull n = label(buf, n);
485 8ad51794 2004-03-25 devnull buf[n] = 0;
486 8ad51794 2004-03-25 devnull qlock(&q.lk);
487 8ad51794 2004-03-25 devnull m = sprint(x, "#%d", q.p);
488 4b970769 2005-03-05 devnull if(fswrite(afd, x, m) != m){
489 4b970769 2005-03-05 devnull fprint(2, "stdout writing address: %r; resetting\n");
490 4b970769 2005-03-05 devnull fswrite(afd, "$", 1);
491 4b970769 2005-03-05 devnull m = fsread(afd, x, sizeof x-1);
492 4b970769 2005-03-05 devnull if(m >= 0){
493 4b970769 2005-03-05 devnull x[m] = 0;
494 4b970769 2005-03-05 devnull q.p = atoi(x);
495 4b970769 2005-03-05 devnull }
496 4b970769 2005-03-05 devnull }
497 8ad51794 2004-03-25 devnull if(fswrite(dfd, buf, n) != n)
498 8ad51794 2004-03-25 devnull error("stdout writing body");
499 8ad51794 2004-03-25 devnull q.p += nrunes(buf, n);
500 8ad51794 2004-03-25 devnull qunlock(&q.lk);
501 8ad51794 2004-03-25 devnull memmove(buf, hold, npart);
502 8ad51794 2004-03-25 devnull }
503 8ad51794 2004-03-25 devnull }
504 8ad51794 2004-03-25 devnull }
505 8ad51794 2004-03-25 devnull
506 efe12411 2005-01-30 devnull char wdir[512];
507 8ad51794 2004-03-25 devnull int
508 8ad51794 2004-03-25 devnull label(char *sr, int n)
509 8ad51794 2004-03-25 devnull {
510 efe12411 2005-01-30 devnull char *sl, *el, *er, *r, *p;
511 8ad51794 2004-03-25 devnull
512 8ad51794 2004-03-25 devnull er = sr+n;
513 8ad51794 2004-03-25 devnull for(r=er-1; r>=sr; r--)
514 8ad51794 2004-03-25 devnull if(*r == '\007')
515 8ad51794 2004-03-25 devnull break;
516 8ad51794 2004-03-25 devnull if(r < sr)
517 8ad51794 2004-03-25 devnull return n;
518 8ad51794 2004-03-25 devnull
519 8ad51794 2004-03-25 devnull el = r+1;
520 efe12411 2005-01-30 devnull if(el-sr > sizeof wdir - strlen(name) - 20)
521 efe12411 2005-01-30 devnull sr = el - sizeof wdir - strlen(name) - 20;
522 8ad51794 2004-03-25 devnull for(sl=el-3; sl>=sr; sl--)
523 8ad51794 2004-03-25 devnull if(sl[0]=='\033' && sl[1]==']' && sl[2]==';')
524 8ad51794 2004-03-25 devnull break;
525 8ad51794 2004-03-25 devnull if(sl < sr)
526 8ad51794 2004-03-25 devnull return n;
527 8ad51794 2004-03-25 devnull
528 8ad51794 2004-03-25 devnull *r = 0;
529 efe12411 2005-01-30 devnull /*
530 efe12411 2005-01-30 devnull * add /-sysname if not present
531 efe12411 2005-01-30 devnull */
532 efe12411 2005-01-30 devnull snprint(wdir, sizeof wdir, "name %s", sl+3);
533 efe12411 2005-01-30 devnull p = strrchr(wdir, '/');
534 efe12411 2005-01-30 devnull if(p==nil || *(p+1) != '-'){
535 efe12411 2005-01-30 devnull p = wdir+strlen(wdir);
536 efe12411 2005-01-30 devnull if(*(p-1) != '/')
537 efe12411 2005-01-30 devnull *p++ = '/';
538 38c087aa 2005-01-30 devnull *p++ = '-';
539 efe12411 2005-01-30 devnull strcpy(p, name);
540 efe12411 2005-01-30 devnull }
541 efe12411 2005-01-30 devnull strcat(wdir, "\n0\n");
542 8ad51794 2004-03-25 devnull fswrite(ctlfd, wdir, strlen(wdir));
543 8ad51794 2004-03-25 devnull
544 8ad51794 2004-03-25 devnull memmove(sl, el, er-el);
545 8ad51794 2004-03-25 devnull n -= (el-sl);
546 8ad51794 2004-03-25 devnull return n;
547 8ad51794 2004-03-25 devnull }
548 8ad51794 2004-03-25 devnull
549 8ad51794 2004-03-25 devnull int
550 8ad51794 2004-03-25 devnull delete(Event *e)
551 8ad51794 2004-03-25 devnull {
552 8ad51794 2004-03-25 devnull uint q0, q1;
553 8ad51794 2004-03-25 devnull int deltap;
554 8ad51794 2004-03-25 devnull
555 8ad51794 2004-03-25 devnull q0 = e->q0;
556 8ad51794 2004-03-25 devnull q1 = e->q1;
557 8ad51794 2004-03-25 devnull if(q1 <= q.p)
558 8ad51794 2004-03-25 devnull return e->q1-e->q0;
559 8ad51794 2004-03-25 devnull if(q0 >= q.p+ntyper)
560 8ad51794 2004-03-25 devnull return 0;
561 8ad51794 2004-03-25 devnull deltap = 0;
562 8ad51794 2004-03-25 devnull if(q0 < q.p){
563 8ad51794 2004-03-25 devnull deltap = q.p-q0;
564 8ad51794 2004-03-25 devnull q0 = 0;
565 8ad51794 2004-03-25 devnull }else
566 8ad51794 2004-03-25 devnull q0 -= q.p;
567 8ad51794 2004-03-25 devnull if(q1 > q.p+ntyper)
568 8ad51794 2004-03-25 devnull q1 = ntyper;
569 8ad51794 2004-03-25 devnull else
570 8ad51794 2004-03-25 devnull q1 -= q.p;
571 8ad51794 2004-03-25 devnull deltype(q0, q1);
572 8ad51794 2004-03-25 devnull return deltap;
573 8ad51794 2004-03-25 devnull }
574 8ad51794 2004-03-25 devnull
575 8ad51794 2004-03-25 devnull void
576 8ad51794 2004-03-25 devnull addtype(int c, uint p0, char *b, int nb, int nr)
577 8ad51794 2004-03-25 devnull {
578 8ad51794 2004-03-25 devnull int i, w;
579 8ad51794 2004-03-25 devnull Rune r;
580 8ad51794 2004-03-25 devnull uint p;
581 8ad51794 2004-03-25 devnull char *b0;
582 8ad51794 2004-03-25 devnull
583 8ad51794 2004-03-25 devnull for(i=0; i<nb; i+=w){
584 8ad51794 2004-03-25 devnull w = chartorune(&r, b+i);
585 8ad51794 2004-03-25 devnull if((r==0x7F||r==3) && c=='K'){
586 8ad51794 2004-03-25 devnull write(rcfd, "\x7F", 1);
587 8ad51794 2004-03-25 devnull /* toss all typing */
588 8ad51794 2004-03-25 devnull q.p += ntyper+nr;
589 8ad51794 2004-03-25 devnull ntypebreak = 0;
590 8ad51794 2004-03-25 devnull ntypeb = 0;
591 8ad51794 2004-03-25 devnull ntyper = 0;
592 8ad51794 2004-03-25 devnull /* buglet: more than one delete ignored */
593 8ad51794 2004-03-25 devnull return;
594 8ad51794 2004-03-25 devnull }
595 8ad51794 2004-03-25 devnull if(r=='\n' || r==0x04)
596 8ad51794 2004-03-25 devnull ntypebreak++;
597 8ad51794 2004-03-25 devnull }
598 8ad51794 2004-03-25 devnull typing = realloc(typing, ntypeb+nb);
599 8ad51794 2004-03-25 devnull if(typing == nil)
600 8ad51794 2004-03-25 devnull error("realloc");
601 8ad51794 2004-03-25 devnull if(p0 == ntyper)
602 8ad51794 2004-03-25 devnull memmove(typing+ntypeb, b, nb);
603 8ad51794 2004-03-25 devnull else{
604 8ad51794 2004-03-25 devnull b0 = typing;
605 8ad51794 2004-03-25 devnull for(p=0; p<p0 && b0<typing+ntypeb; p++){
606 8ad51794 2004-03-25 devnull w = chartorune(&r, b0+i);
607 8ad51794 2004-03-25 devnull b0 += w;
608 8ad51794 2004-03-25 devnull }
609 8ad51794 2004-03-25 devnull if(p != p0)
610 8ad51794 2004-03-25 devnull error("typing: findrune");
611 8ad51794 2004-03-25 devnull memmove(b0+nb, b0, (typing+ntypeb)-b0);
612 8ad51794 2004-03-25 devnull memmove(b0, b, nb);
613 8ad51794 2004-03-25 devnull }
614 8ad51794 2004-03-25 devnull ntypeb += nb;
615 8ad51794 2004-03-25 devnull ntyper += nr;
616 8ad51794 2004-03-25 devnull }
617 8ad51794 2004-03-25 devnull
618 8ad51794 2004-03-25 devnull void
619 8ad51794 2004-03-25 devnull sendtype(int fd0)
620 8ad51794 2004-03-25 devnull {
621 8ad51794 2004-03-25 devnull int i, n, nr;
622 8ad51794 2004-03-25 devnull
623 8ad51794 2004-03-25 devnull while(ntypebreak){
624 8ad51794 2004-03-25 devnull for(i=0; i<ntypeb; i++)
625 8ad51794 2004-03-25 devnull if(typing[i]=='\n' || typing[i]==0x04){
626 4f30f3b4 2004-03-30 devnull n = i+1;
627 8ad51794 2004-03-25 devnull i++;
628 8ad51794 2004-03-25 devnull if(write(fd0, typing, n) != n)
629 8ad51794 2004-03-25 devnull error("sending to program");
630 8ad51794 2004-03-25 devnull nr = nrunes(typing, i);
631 8ad51794 2004-03-25 devnull q.p += nr;
632 8ad51794 2004-03-25 devnull ntyper -= nr;
633 8ad51794 2004-03-25 devnull ntypeb -= i;
634 8ad51794 2004-03-25 devnull memmove(typing, typing+i, ntypeb);
635 8ad51794 2004-03-25 devnull ntypebreak--;
636 8ad51794 2004-03-25 devnull goto cont2;
637 8ad51794 2004-03-25 devnull }
638 8ad51794 2004-03-25 devnull print("no breakchar\n");
639 8ad51794 2004-03-25 devnull ntypebreak = 0;
640 8ad51794 2004-03-25 devnull cont2:;
641 8ad51794 2004-03-25 devnull }
642 8ad51794 2004-03-25 devnull }
643 8ad51794 2004-03-25 devnull
644 8ad51794 2004-03-25 devnull void
645 8ad51794 2004-03-25 devnull deltype(uint p0, uint p1)
646 8ad51794 2004-03-25 devnull {
647 8ad51794 2004-03-25 devnull int w;
648 8ad51794 2004-03-25 devnull uint p, b0, b1;
649 8ad51794 2004-03-25 devnull Rune r;
650 8ad51794 2004-03-25 devnull
651 8ad51794 2004-03-25 devnull /* advance to p0 */
652 8ad51794 2004-03-25 devnull b0 = 0;
653 8ad51794 2004-03-25 devnull for(p=0; p<p0 && b0<ntypeb; p++){
654 8ad51794 2004-03-25 devnull w = chartorune(&r, typing+b0);
655 8ad51794 2004-03-25 devnull b0 += w;
656 8ad51794 2004-03-25 devnull }
657 8ad51794 2004-03-25 devnull if(p != p0)
658 8ad51794 2004-03-25 devnull error("deltype 1");
659 8ad51794 2004-03-25 devnull /* advance to p1 */
660 8ad51794 2004-03-25 devnull b1 = b0;
661 8ad51794 2004-03-25 devnull for(; p<p1 && b1<ntypeb; p++){
662 8ad51794 2004-03-25 devnull w = chartorune(&r, typing+b1);
663 8ad51794 2004-03-25 devnull b1 += w;
664 8ad51794 2004-03-25 devnull if(r=='\n' || r==0x04)
665 8ad51794 2004-03-25 devnull ntypebreak--;
666 8ad51794 2004-03-25 devnull }
667 8ad51794 2004-03-25 devnull if(p != p1)
668 8ad51794 2004-03-25 devnull error("deltype 2");
669 8ad51794 2004-03-25 devnull memmove(typing+b0, typing+b1, ntypeb-b1);
670 8ad51794 2004-03-25 devnull ntypeb -= b1-b0;
671 8ad51794 2004-03-25 devnull ntyper -= p1-p0;
672 8ad51794 2004-03-25 devnull }
673 8ad51794 2004-03-25 devnull
674 8ad51794 2004-03-25 devnull void
675 452c0935 2005-01-04 devnull type(Event *e, int fd0, CFid *afd, CFid *dfd)
676 8ad51794 2004-03-25 devnull {
677 8ad51794 2004-03-25 devnull int m, n, nr;
678 8ad51794 2004-03-25 devnull char buf[128];
679 8ad51794 2004-03-25 devnull
680 8ad51794 2004-03-25 devnull if(e->nr > 0)
681 8ad51794 2004-03-25 devnull addtype(e->c1, e->q0-q.p, e->b, e->nb, e->nr);
682 8ad51794 2004-03-25 devnull else{
683 8ad51794 2004-03-25 devnull m = e->q0;
684 8ad51794 2004-03-25 devnull while(m < e->q1){
685 8ad51794 2004-03-25 devnull n = sprint(buf, "#%d", m);
686 8ad51794 2004-03-25 devnull fswrite(afd, buf, n);
687 8ad51794 2004-03-25 devnull n = fsread(dfd, buf, sizeof buf);
688 8ad51794 2004-03-25 devnull nr = nrunes(buf, n);
689 8ad51794 2004-03-25 devnull while(m+nr > e->q1){
690 8ad51794 2004-03-25 devnull do; while(n>0 && (buf[--n]&0xC0)==0x80);
691 8ad51794 2004-03-25 devnull --nr;
692 8ad51794 2004-03-25 devnull }
693 8ad51794 2004-03-25 devnull if(n == 0)
694 8ad51794 2004-03-25 devnull break;
695 8ad51794 2004-03-25 devnull addtype(e->c1, m-q.p, buf, n, nr);
696 8ad51794 2004-03-25 devnull m += nr;
697 8ad51794 2004-03-25 devnull }
698 8ad51794 2004-03-25 devnull }
699 8ad51794 2004-03-25 devnull sendtype(fd0);
700 8ad51794 2004-03-25 devnull }
701 8ad51794 2004-03-25 devnull
702 8ad51794 2004-03-25 devnull void
703 452c0935 2005-01-04 devnull sende(Event *e, int fd0, CFid *cfd, CFid *afd, CFid *dfd, int donl)
704 8ad51794 2004-03-25 devnull {
705 8ad51794 2004-03-25 devnull int l, m, n, nr, lastc, end;
706 8ad51794 2004-03-25 devnull char abuf[16], buf[128];
707 8ad51794 2004-03-25 devnull
708 8ad51794 2004-03-25 devnull end = q.p+ntyper;
709 8ad51794 2004-03-25 devnull l = sprint(abuf, "#%d", end);
710 8ad51794 2004-03-25 devnull fswrite(afd, abuf, l);
711 8ad51794 2004-03-25 devnull if(e->nr > 0){
712 8ad51794 2004-03-25 devnull fswrite(dfd, e->b, e->nb);
713 8ad51794 2004-03-25 devnull addtype(e->c1, ntyper, e->b, e->nb, e->nr);
714 8ad51794 2004-03-25 devnull lastc = e->r[e->nr-1];
715 8ad51794 2004-03-25 devnull }else{
716 8ad51794 2004-03-25 devnull m = e->q0;
717 8ad51794 2004-03-25 devnull lastc = 0;
718 8ad51794 2004-03-25 devnull while(m < e->q1){
719 8ad51794 2004-03-25 devnull n = sprint(buf, "#%d", m);
720 8ad51794 2004-03-25 devnull fswrite(afd, buf, n);
721 8ad51794 2004-03-25 devnull n = fsread(dfd, buf, sizeof buf);
722 8ad51794 2004-03-25 devnull nr = nrunes(buf, n);
723 8ad51794 2004-03-25 devnull while(m+nr > e->q1){
724 8ad51794 2004-03-25 devnull do; while(n>0 && (buf[--n]&0xC0)==0x80);
725 8ad51794 2004-03-25 devnull --nr;
726 8ad51794 2004-03-25 devnull }
727 8ad51794 2004-03-25 devnull if(n == 0)
728 8ad51794 2004-03-25 devnull break;
729 8ad51794 2004-03-25 devnull l = sprint(abuf, "#%d", end);
730 8ad51794 2004-03-25 devnull fswrite(afd, abuf, l);
731 8ad51794 2004-03-25 devnull fswrite(dfd, buf, n);
732 8ad51794 2004-03-25 devnull addtype(e->c1, ntyper, buf, n, nr);
733 8ad51794 2004-03-25 devnull lastc = buf[n-1];
734 8ad51794 2004-03-25 devnull m += nr;
735 8ad51794 2004-03-25 devnull end += nr;
736 8ad51794 2004-03-25 devnull }
737 8ad51794 2004-03-25 devnull }
738 8ad51794 2004-03-25 devnull if(donl && lastc!='\n'){
739 8ad51794 2004-03-25 devnull fswrite(dfd, "\n", 1);
740 8ad51794 2004-03-25 devnull addtype(e->c1, ntyper, "\n", 1, 1);
741 8ad51794 2004-03-25 devnull }
742 8ad51794 2004-03-25 devnull fswrite(cfd, "dot=addr", 8);
743 8ad51794 2004-03-25 devnull sendtype(fd0);
744 8ad51794 2004-03-25 devnull }