Blame


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