19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <fcall.h>
49a747e4fSDavid du Colombier #include <thread.h>
59a747e4fSDavid du Colombier #include <9p.h>
69a747e4fSDavid du Colombier #include "dat.h"
79a747e4fSDavid du Colombier
89a747e4fSDavid du Colombier Channel *fschan;
99a747e4fSDavid du Colombier Channel *writechan;
109a747e4fSDavid du Colombier
119a747e4fSDavid du Colombier static File *devcons, *devnew;
129a747e4fSDavid du Colombier
139a747e4fSDavid du Colombier static void
fsread(Req * r)149a747e4fSDavid du Colombier fsread(Req *r)
159a747e4fSDavid du Colombier {
169a747e4fSDavid du Colombier Fsevent e;
179a747e4fSDavid du Colombier
189a747e4fSDavid du Colombier if(r->fid->file == devnew){
199a747e4fSDavid du Colombier if(r->fid->aux==nil){
209a747e4fSDavid du Colombier respond(r, "phase error");
219a747e4fSDavid du Colombier return;
229a747e4fSDavid du Colombier }
239a747e4fSDavid du Colombier readstr(r, r->fid->aux);
249a747e4fSDavid du Colombier respond(r, nil);
259a747e4fSDavid du Colombier return;
269a747e4fSDavid du Colombier }
279a747e4fSDavid du Colombier
289a747e4fSDavid du Colombier assert(r->fid->file == devcons);
299a747e4fSDavid du Colombier e.type = 'r';
309a747e4fSDavid du Colombier e.r = r;
319a747e4fSDavid du Colombier send(fschan, &e);
329a747e4fSDavid du Colombier }
339a747e4fSDavid du Colombier
349a747e4fSDavid du Colombier static void
fsflush(Req * r)359a747e4fSDavid du Colombier fsflush(Req *r)
369a747e4fSDavid du Colombier {
379a747e4fSDavid du Colombier Fsevent e;
389a747e4fSDavid du Colombier
399a747e4fSDavid du Colombier e.type = 'f';
409a747e4fSDavid du Colombier e.r = r;
419a747e4fSDavid du Colombier send(fschan, &e);
429a747e4fSDavid du Colombier }
439a747e4fSDavid du Colombier
449a747e4fSDavid du Colombier static void
fswrite(Req * r)459a747e4fSDavid du Colombier fswrite(Req *r)
469a747e4fSDavid du Colombier {
479a747e4fSDavid du Colombier static Event *e[4];
489a747e4fSDavid du Colombier Event *ep;
49*8cd281c0SDavid du Colombier int i, j, ei, nb, wid, pid;
509a747e4fSDavid du Colombier Rune rune;
519a747e4fSDavid du Colombier char *s;
529a747e4fSDavid du Colombier char tmp[UTFmax], *t;
539a747e4fSDavid du Colombier static int n, partial;
549a747e4fSDavid du Colombier
559a747e4fSDavid du Colombier if(r->fid->file == devnew){
569a747e4fSDavid du Colombier if(r->fid->aux){
579a747e4fSDavid du Colombier respond(r, "already created a window");
589a747e4fSDavid du Colombier return;
599a747e4fSDavid du Colombier }
609a747e4fSDavid du Colombier s = emalloc(r->ifcall.count+1);
619a747e4fSDavid du Colombier memmove(s, r->ifcall.data, r->ifcall.count);
629a747e4fSDavid du Colombier s[r->ifcall.count] = 0;
639a747e4fSDavid du Colombier pid = strtol(s, &t, 0);
649a747e4fSDavid du Colombier if(*t==' ')
659a747e4fSDavid du Colombier t++;
669a747e4fSDavid du Colombier i = newpipewin(pid, t);
679a747e4fSDavid du Colombier free(s);
689a747e4fSDavid du Colombier s = emalloc(32);
699a747e4fSDavid du Colombier sprint(s, "%lud", (ulong)i);
709a747e4fSDavid du Colombier r->fid->aux = s;
719a747e4fSDavid du Colombier r->ofcall.count = r->ifcall.count;
729a747e4fSDavid du Colombier respond(r, nil);
739a747e4fSDavid du Colombier return;
749a747e4fSDavid du Colombier }
759a747e4fSDavid du Colombier
769a747e4fSDavid du Colombier assert(r->fid->file == devcons);
779a747e4fSDavid du Colombier
789a747e4fSDavid du Colombier if(e[0] == nil){
799a747e4fSDavid du Colombier for(i=0; i<nelem(e); i++){
809a747e4fSDavid du Colombier e[i] = emalloc(sizeof(Event));
819a747e4fSDavid du Colombier e[i]->c1 = 'S';
829a747e4fSDavid du Colombier }
839a747e4fSDavid du Colombier }
849a747e4fSDavid du Colombier
859a747e4fSDavid du Colombier ep = e[n];
869a747e4fSDavid du Colombier n = (n+1)%nelem(e);
879a747e4fSDavid du Colombier assert(r->ifcall.count <= 8192); /* is this guaranteed by lib9p? */
889a747e4fSDavid du Colombier nb = r->ifcall.count;
899a747e4fSDavid du Colombier memmove(ep->b+partial, r->ifcall.data, nb);
909a747e4fSDavid du Colombier nb += partial;
919a747e4fSDavid du Colombier ep->b[nb] = '\0';
929a747e4fSDavid du Colombier if(strlen(ep->b) < nb){ /* nulls in data */
939a747e4fSDavid du Colombier t = ep->b;
949a747e4fSDavid du Colombier for(i=j=0; i<nb; i++)
959a747e4fSDavid du Colombier if(ep->b[i] != '\0')
969a747e4fSDavid du Colombier t[j++] = ep->b[i];
979a747e4fSDavid du Colombier nb = j;
989a747e4fSDavid du Colombier t[j] = '\0';
999a747e4fSDavid du Colombier }
100*8cd281c0SDavid du Colombier ei = nb>8192? 8192 : nb;
1019a747e4fSDavid du Colombier /* process bytes into runes, transferring terminal partial runes into next buffer */
102*8cd281c0SDavid du Colombier for(i=j=0; i<ei && fullrune(ep->b+i, ei-i); i+=wid,j++)
1039a747e4fSDavid du Colombier wid = chartorune(&rune, ep->b+i);
1049a747e4fSDavid du Colombier memmove(tmp, ep->b+i, nb-i);
1059a747e4fSDavid du Colombier partial = nb-i;
1069a747e4fSDavid du Colombier ep->nb = i;
1079a747e4fSDavid du Colombier ep->nr = j;
1089a747e4fSDavid du Colombier ep->b[i] = '\0';
1099a747e4fSDavid du Colombier if(i != 0){
1109a747e4fSDavid du Colombier sendp(win->cevent, ep);
1119a747e4fSDavid du Colombier recvp(writechan);
1129a747e4fSDavid du Colombier }
1139a747e4fSDavid du Colombier partial = nb-i;
1149a747e4fSDavid du Colombier memmove(e[n]->b, tmp, partial);
1159a747e4fSDavid du Colombier r->ofcall.count = r->ifcall.count;
1169a747e4fSDavid du Colombier respond(r, nil);
1179a747e4fSDavid du Colombier }
1189a747e4fSDavid du Colombier
1199a747e4fSDavid du Colombier void
fsdestroyfid(Fid * fid)1209a747e4fSDavid du Colombier fsdestroyfid(Fid *fid)
1219a747e4fSDavid du Colombier {
1229a747e4fSDavid du Colombier if(fid->aux)
1239a747e4fSDavid du Colombier free(fid->aux);
1249a747e4fSDavid du Colombier }
1259a747e4fSDavid du Colombier
1269a747e4fSDavid du Colombier Srv fs = {
1279a747e4fSDavid du Colombier .read= fsread,
1289a747e4fSDavid du Colombier .write= fswrite,
1299a747e4fSDavid du Colombier .flush= fsflush,
1309a747e4fSDavid du Colombier .destroyfid= fsdestroyfid,
1316b6b9ac8SDavid du Colombier .leavefdsopen= 1,
1329a747e4fSDavid du Colombier };
1339a747e4fSDavid du Colombier
1349a747e4fSDavid du Colombier void
mountcons(void)1359a747e4fSDavid du Colombier mountcons(void)
1369a747e4fSDavid du Colombier {
1379a747e4fSDavid du Colombier fschan = chancreate(sizeof(Fsevent), 0);
1389a747e4fSDavid du Colombier writechan = chancreate(sizeof(void*), 0);
1399a747e4fSDavid du Colombier fs.tree = alloctree("win", "win", DMDIR|0555, nil);
1409a747e4fSDavid du Colombier devcons = createfile(fs.tree->root, "cons", "win", 0666, nil);
1419a747e4fSDavid du Colombier if(devcons == nil)
1429a747e4fSDavid du Colombier sysfatal("creating /dev/cons: %r");
1439a747e4fSDavid du Colombier devnew = createfile(fs.tree->root, "wnew", "win", 0666, nil);
1449a747e4fSDavid du Colombier if(devnew == nil)
1459a747e4fSDavid du Colombier sysfatal("creating /dev/wnew: %r");
1469a747e4fSDavid du Colombier threadpostmountsrv(&fs, nil, "/dev", MBEFORE);
1479a747e4fSDavid du Colombier }
148