ref: 6ddbe25d19bfa5a8c305e9e4292fa3ed0d24426a
parent: 169db43ad91d6873a3ba3cd1396aaaf96e9d4dc5
author: cinap_lenrek <[email protected]>
date: Fri Dec 12 16:09:49 EST 2014
acme/win: remove old crap
--- a/acme/bin/source/win/_fs.c
+++ /dev/null
@@ -1,146 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include <thread.h>
-#include <9p.h>
-#include "dat.h"
-
-Channel *fschan;
-Channel *writechan;
-
-static File *devcons, *devnew;
-
-static void
-fsread(Req *r)
-{
- Fsevent e;
-
- if(r->fid->file == devnew){
- if(r->fid->aux==nil){
- respond(r, "phase error");
- return;
- }
- readstr(r, r->fid->aux);
- respond(r, nil);
- return;
- }
-
- assert(r->fid->file == devcons);
- e.type = 'r';
- e.r = r;
- send(fschan, &e);
-}
-
-static void
-fsflush(Req *r)
-{
- Fsevent e;
-
- e.type = 'f';
- e.r = r;
- send(fschan, &e);
-}
-
-static void
-fswrite(Req *r)
-{
- static Event *e[4];
- Event *ep;
- int i, j, nb, wid, pid;
- Rune rune;
- char *s;
- char tmp[UTFmax], *t;
- static int n, partial;
-
- if(r->fid->file == devnew){
- if(r->fid->aux){
- respond(r, "already created a window");
- return;
- }
- s = emalloc(r->ifcall.count+1);
- memmove(s, r->ifcall.data, r->ifcall.count);
- s[r->ifcall.count] = 0;
- pid = strtol(s, &t, 0);
- if(*t==' ')
- t++;
- i = newpipewin(pid, t);
- free(s);
- s = emalloc(32);
- sprint(s, "%lud", (ulong)i);
- r->fid->aux = s;
- r->ofcall.count = r->ifcall.count;
- respond(r, nil);
- return;
- }
-
- assert(r->fid->file == devcons);
-
- if(e[0] == nil){
- for(i=0; i<nelem(e); i++){
- e[i] = emalloc(sizeof(Event));
- e[i]->c1 = 'S';
- }
- }
-
- ep = e[n];
- n = (n+1)%nelem(e);
- assert(r->ifcall.count <= 8192); /* is this guaranteed by lib9p? */
- nb = r->ifcall.count;
- memmove(ep->b+partial, r->ifcall.data, nb);
- nb += partial;
- ep->b[nb] = '\0';
- if(strlen(ep->b) < nb){ /* nulls in data */
- t = ep->b;
- for(i=j=0; i<nb; i++)
- if(ep->b[i] != '\0')
- t[j++] = ep->b[i];
- nb = j;
- t[j] = '\0';
- }
- /* process bytes into runes, transferring terminal partial runes into next buffer */
- for(i=j=0; i<nb && fullrune(ep->b+i, nb-i); i+=wid,j++)
- wid = chartorune(&rune, ep->b+i);
- memmove(tmp, ep->b+i, nb-i);
- partial = nb-i;
- ep->nb = i;
- ep->nr = j;
- ep->b[i] = '\0';
- if(i != 0){
- sendp(win->cevent, ep);
- recvp(writechan);
- }
- partial = nb-i;
- memmove(e[n]->b, tmp, partial);
- r->ofcall.count = r->ifcall.count;
- respond(r, nil);
-}
-
-void
-fsdestroyfid(Fid *fid)
-{
- if(fid->aux)
- free(fid->aux);
-}
-
-Srv fs = {
-.read= fsread,
-.write= fswrite,
-.flush= fsflush,
-.destroyfid= fsdestroyfid,
-.leavefdsopen= 1,
-};
-
-void
-mountcons(void)
-{
- fschan = chancreate(sizeof(Fsevent), 0);
- writechan = chancreate(sizeof(void*), 0);
- fs.tree = alloctree("win", "win", DMDIR|0555, nil);
- devcons = createfile(fs.tree->root, "cons", "win", 0666, nil);
- if(devcons == nil)
- sysfatal("creating /dev/cons: %r");
- devnew = createfile(fs.tree->root, "wnew", "win", 0666, nil);
- if(devnew == nil)
- sysfatal("creating /dev/wnew: %r");
- threadpostmountsrv(&fs, nil, "/dev", MBEFORE);
-}
--- a/acme/bin/source/win/_main.c
+++ /dev/null
@@ -1,651 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <thread.h>
-#include <fcall.h>
-#include <9p.h>
-#include <ctype.h>
-#include "dat.h"
-
-void mainctl(void*);
-void startcmd(char *[], int*);
-void stdout2body(void*);
-
-int debug;
-int notepg;
-int eraseinput;
-int dirty = 0;
-
-Window *win; /* the main window */
-
-void
-usage(void)
-{
- fprint(2, "usage: win [command]\n");
- threadexitsall("usage");
-}
-
-void
-threadmain(int argc, char *argv[])
-{
- int i, j;
- char *dir, *tag, *name;
- char buf[1024], **av;
-
- quotefmtinstall();
- rfork(RFNAMEG);
- ARGBEGIN{
- case 'd':
- debug = 1;
- chatty9p++;
- break;
- case 'e':
- eraseinput = 1;
- break;
- case 'D':
-{extern int _threaddebuglevel;
- _threaddebuglevel = 1<<20;
-}
- }ARGEND
-
- if(argc == 0){
- av = emalloc(3*sizeof(char*));
- av[0] = "rc";
- av[1] = "-i";
- name = getenv("sysname");
- }else{
- av = argv;
- name = utfrrune(av[0], '/');
- if(name)
- name++;
- else
- name = av[0];
- }
-
- if(getwd(buf, sizeof buf) == 0)
- dir = "/";
- else
- dir = buf;
- dir = estrdup(dir);
- tag = estrdup(dir);
- tag = eappend(estrdup(tag), "/-", name);
- win = newwindow();
- snprint(buf, sizeof buf, "%d", win->id);
- putenv("winid", buf);
- winname(win, tag);
- wintagwrite(win, "Send Noscroll", 5+8);
- threadcreate(mainctl, win, STACK);
- mountcons();
- threadcreate(fsloop, nil, STACK);
- startpipe();
- startcmd(av, ¬epg);
-
- strcpy(buf, "win");
- j = 3;
- for(i=0; i<argc && j+1+strlen(argv[i])+1<sizeof buf; i++){
- strcpy(buf+j, " ");
- strcpy(buf+j+1, argv[i]);
- j += 1+strlen(argv[i]);
- }
-
- ctlprint(win->ctl, "scroll");
- winsetdump(win, dir, buf);
-}
-
-int
-EQUAL(char *s, char *t)
-{
- while(tolower(*s) == tolower(*t++))
- if(*s++ == '\0')
- return 1;
- return 0;
-}
-
-int
-command(Window *w, char *s)
-{
- while(*s==' ' || *s=='\t' || *s=='\n')
- s++;
- if(strcmp(s, "Delete")==0){
- windel(w, 1);
- threadexitsall(nil);
- return 1;
- }
- if(strcmp(s, "Del")==0){
- if(windel(w, 0))
- threadexitsall(nil);
- return 1;
- }
- if(EQUAL(s, "scroll")){
- ctlprint(w->ctl, "scroll\nshow");
- return 1;
- }
- if(EQUAL(s, "noscroll")){
- ctlprint(w->ctl, "noscroll");
- return 1;
- }
- return 0;
-}
-
-static long
-utfncpy(char *to, char *from, int n)
-{
- char *end, *e;
-
- e = to+n;
- if(to >= e)
- return 0;
- end = memccpy(to, from, '\0', e - to);
- if(end == nil){
- end = e;
- if(end[-1]&0x80){
- if(end-2>=to && (end[-2]&0xE0)==0xC0)
- return end-to;
- if(end-3>=to && (end[-3]&0xF0)==0xE0)
- return end-to;
- while(end>to && (*--end&0xC0)==0x80)
- ;
- }
- }else
- end--;
- return end - to;
-}
-
-/* sendinput and fsloop run in the same proc (can't interrupt each other). */
-static Req *q;
-static Req **eq;
-static int
-__sendinput(Window *w, ulong q0, ulong q1)
-{
- char *s, *t;
- int n, nb, eofchar;
- static int partial;
- static char tmp[UTFmax];
- Req *r;
- Rune rune;
-
- if(!q)
- return 0;
-
- r = q;
- n = 0;
- if(partial){
- Partial:
- nb = partial;
- if(nb > r->ifcall.count)
- nb = r->ifcall.count;
- memmove(r->ofcall.data, tmp, nb);
- if(nb!=partial)
- memmove(tmp, tmp+nb, partial-nb);
- partial -= nb;
- q = r->aux;
- if(q == nil)
- eq = &q;
- r->aux = nil;
- r->ofcall.count = nb;
- if(debug)
- fprint(2, "satisfy read with partial\n");
- respond(r, nil);
- return n;
- }
- if(q0==q1)
- return 0;
- s = emalloc((q1-q0)*UTFmax+1);
- n = winread(w, q0, q1, s);
- s[n] = '\0';
- t = strpbrk(s, "\n\004");
- if(t == nil){
- free(s);
- return 0;
- }
- r = q;
- eofchar = 0;
- if(*t == '\004'){
- eofchar = 1;
- *t = '\0';
- }else
- *++t = '\0';
- nb = utfncpy((char*)r->ofcall.data, s, r->ifcall.count);
- if(nb==0 && s<t && r->ifcall.count > 0){
- partial = utfncpy(tmp, s, UTFmax);
- assert(partial > 0);
- chartorune(&rune, tmp);
- partial = runelen(rune);
- free(s);
- n = 1;
- goto Partial;
- }
- n = utfnlen(r->ofcall.data, nb);
- if(nb==strlen(s) && eofchar)
- n++;
- r->ofcall.count = nb;
- q = r->aux;
- if(q == nil)
- eq = &q;
- r->aux = nil;
- if(debug)
- fprint(2, "read returns %lud-%lud: %.*q\n", q0, q0+n, n, r->ofcall.data);
- respond(r, nil);
- return n;
-}
-
-static int
-_sendinput(Window *w, ulong q0, ulong *q1)
-{
- char buf[32];
- int n;
-
- n = __sendinput(w, q0, *q1);
- if(!n || !eraseinput)
- return n;
- /* erase q0 to q0+n */
- sprint(buf, "#%lud,#%lud", q0, q0+n);
- winsetaddr(w, buf, 0);
- write(w->data, buf, 0);
- *q1 -= n;
- return 0;
-}
-
-int
-sendinput(Window *w, ulong q0, ulong *q1)
-{
- ulong n;
- Req *oq;
-
- n = 0;
- do {
- oq = q;
- n += _sendinput(w, q0+n, q1);
- } while(q != oq);
- return n;
-}
-
-Event esendinput;
-void
-fsloop(void*)
-{
- Fsevent e;
- Req **l, *r;
-
- eq = &q;
- memset(&esendinput, 0, sizeof esendinput);
- esendinput.c1 = 'C';
- for(;;){
- while(recv(fschan, &e) == -1)
- ;
- r = e.r;
- switch(e.type){
- case 'r':
- *eq = r;
- r->aux = nil;
- eq = &r->aux;
- /* call sendinput with hostpt and endpt */
- sendp(win->cevent, &esendinput);
- break;
- case 'f':
- for(l=&q; *l; l=&(*l)->aux){
- if(*l == r->oldreq){
- *l = (*l)->aux;
- if(*l == nil)
- eq = l;
- respond(r->oldreq, "interrupted");
- break;
- }
- }
- respond(r, nil);
- break;
- }
- }
-}
-
-void
-sendit(char *s)
-{
-// char tmp[32];
-
- write(win->body, s, strlen(s));
-/*
- * RSC: The problem here is that other procs can call sendit,
- * so we lose our single-threadedness if we call sendinput.
- * In fact, we don't even have the right queue memory,
- * I think that we'll get a write event from the body write above,
- * and we can do the sendinput then, from our single thread.
- *
- * I still need to figure out how to test this assertion for
- * programs that use /srv/win*
- *
- winselect(win, "$", 0);
- seek(win->addr, 0UL, 0);
- if(read(win->addr, tmp, 2*12) == 2*12)
- hostpt += sendinput(win, hostpt, atol(tmp), );
- */
-}
-
-void
-execevent(Window *w, Event *e, int (*command)(Window*, char*))
-{
- Event *ea, *e2;
- int n, na, len, needfree;
- char *s, *t;
-
- ea = nil;
- e2 = nil;
- if(e->flag & 2)
- e2 = recvp(w->cevent);
- if(e->flag & 8){
- ea = recvp(w->cevent);
- na = ea->nb;
- recvp(w->cevent);
- }else
- na = 0;
-
- needfree = 0;
- s = e->b;
- if(e->nb==0 && (e->flag&2)){
- s = e2->b;
- e->q0 = e2->q0;
- e->q1 = e2->q1;
- e->nb = e2->nb;
- }
- if(e->nb==0 && e->q0<e->q1){
- /* fetch data from window */
- s = emalloc((e->q1-e->q0)*UTFmax+2);
- n = winread(w, e->q0, e->q1, s);
- s[n] = '\0';
- needfree = 1;
- }else
- if(na){
- t = emalloc(strlen(s)+1+na+2);
- sprint(t, "%s %s", s, ea->b);
- if(needfree)
- free(s);
- s = t;
- needfree = 1;
- }
-
- /* if it's a known command, do it */
- /* if it's a long message, it can't be for us anyway */
- if(!command(w, s) && s[0]!='\0'){ /* send it as typed text */
- /* if it's a built-in from the tag, send it back */
- if(e->flag & 1)
- fprint(w->event, "%c%c%d %d\n", e->c1, e->c2, e->q0, e->q1);
- else{ /* send text to main window */
- len = strlen(s);
- if(len>0 && s[len-1]!='\n' && s[len-1]!='\004'){
- if(!needfree){
- /* if(needfree), we left room for a newline before */
- t = emalloc(len+2);
- strcpy(t, s);
- s = t;
- needfree = 1;
- }
- s[len++] = '\n';
- s[len] = '\0';
- }
- sendit(s);
- }
- }
- if(needfree)
- free(s);
-}
-
-int
-hasboundary(Rune *r, int nr)
-{
- int i;
-
- for(i=0; i<nr; i++)
- if(r[i]=='\n' || r[i]=='\004')
- return 1;
- return 0;
-}
-
-void
-mainctl(void *v)
-{
- Window *w;
- Event *e;
- int delta, pendingS, pendingK;
- ulong hostpt, endpt;
- char tmp[32];
-
- w = v;
- proccreate(wineventproc, w, STACK);
-
- hostpt = 0;
- endpt = 0;
- winsetaddr(w, "0", 0);
- pendingS = 0;
- pendingK = 0;
- for(;;){
- if(debug)
- fprint(2, "input range %lud-%lud\n", hostpt, endpt);
- e = recvp(w->cevent);
- if(debug)
- fprint(2, "msg: %C %C %d %d %d %d %q\n",
- e->c1 ? e->c1 : ' ', e->c2 ? e->c2 : ' ', e->q0, e->q1, e->flag, e->nb, e->b);
- switch(e->c1){
- default:
- Unknown:
- fprint(2, "unknown message %c%c\n", e->c1, e->c2);
- break;
-
- case 'C': /* input needed for /dev/cons */
- if(pendingS)
- pendingK = 1;
- else
- hostpt += sendinput(w, hostpt, &endpt);
- break;
-
- case 'S': /* output to stdout */
- sprint(tmp, "#%lud", hostpt);
- winsetaddr(w, tmp, 0);
- write(w->data, e->b, e->nb);
- pendingS += utfnlen(e->b, e->nb);
- break;
-
- case 'E': /* write to tag or body; body happens due to sendit */
- delta = e->q1-e->q0;
- if(e->c2=='I'){
- endpt += delta;
- if(e->q0 < hostpt)
- hostpt += delta;
- else
- hostpt += sendinput(w, hostpt, &endpt);
- break;
- }
- if(!islower(e->c2))
- fprint(2, "win msg: %C %C %d %d %d %d %q\n",
- e->c1, e->c2, e->q0, e->q1, e->flag, e->nb, e->b);
- break;
-
- case 'F': /* generated by our actions (specifically case 'S' above) */
- delta = e->q1-e->q0;
- if(e->c2=='D'){
- /* we know about the delete by _sendinput */
- break;
- }
- if(e->c2=='I'){
- pendingS -= e->q1 - e->q0;
- if(pendingS < 0)
- fprint(2, "win: pendingS = %d\n", pendingS);
- if(e->q0 != hostpt)
- fprint(2, "win: insert at %d expected %lud\n", e->q0, hostpt);
- endpt += delta;
- hostpt += delta;
- sendp(writechan, nil);
- if(pendingS == 0 && pendingK){
- pendingK = 0;
- hostpt += sendinput(w, hostpt, &endpt);
- }
- break;
- }
- if(!islower(e->c2))
- fprint(2, "win msg: %C %C %d %d %d %d %q\n",
- e->c1, e->c2, e->q0, e->q1, e->flag, e->nb, e->b);
- break;
-
- case 'K':
- delta = e->q1-e->q0;
- switch(e->c2){
- case 'D':
- endpt -= delta;
- if(e->q1 < hostpt)
- hostpt -= delta;
- else if(e->q0 < hostpt)
- hostpt = e->q0;
- break;
- case 'I':
- delta = e->q1 - e->q0;
- endpt += delta;
- if(endpt < e->q1) /* just in case */
- endpt = e->q1;
- if(e->q0 < hostpt)
- hostpt += delta;
- if(e->nr>0 && e->r[e->nr-1]==0x7F){
- write(notepg, "interrupt", 9);
- hostpt = endpt;
- break;
- }
- if(e->q0 >= hostpt
- && hasboundary(e->r, e->nr)){
- /*
- * If we are between the S message (which
- * we processed by inserting text in the
- * window) and the F message notifying us
- * that the text has been inserted, then our
- * impression of the hostpt and acme's
- * may be different. This could be seen if you
- * hit enter a bunch of times in a con
- * session. To work around the unreliability,
- * only send input if we don't have an S pending.
- * The same race occurs between when a character
- * is typed and when we get notice of it, but
- * since characters tend to be typed at the end
- * of the buffer, we don't run into it. There's
- * no workaround possible for this typing race,
- * since we can't tell when the user has typed
- * something but we just haven't been notified.
- */
- if(pendingS)
- pendingK = 1;
- else
- hostpt += sendinput(w, hostpt, &endpt);
- }
- break;
- }
- break;
-
- case 'M': /* mouse */
- delta = e->q1-e->q0;
- switch(e->c2){
- case 'x':
- case 'X':
- execevent(w, e, command);
- break;
-
- case 'l': /* reflect all searches back to acme */
- case 'L':
- if(e->flag & 2)
- recvp(w->cevent);
- winwriteevent(w, e);
- break;
-
- case 'I':
- endpt += delta;
- if(e->q0 < hostpt)
- hostpt += delta;
- else
- hostpt += sendinput(w, hostpt, &endpt);
- break;
-
- case 'D':
- endpt -= delta;
- if(e->q1 < hostpt)
- hostpt -= delta;
- else if(e->q0 < hostpt)
- hostpt = e->q0;
- break;
- case 'd': /* modify away; we don't care */
- case 'i':
- break;
-
- default:
- goto Unknown;
- }
- }
- }
-}
-
-enum
-{
- NARGS = 100,
- NARGCHAR = 8*1024,
- EXECSTACK = STACK+(NARGS+1)*sizeof(char*)+NARGCHAR
-};
-
-struct Exec
-{
- char **argv;
- Channel *cpid;
-};
-
-int
-lookinbin(char *s)
-{
- if(s[0] == '/')
- return 0;
- if(s[0]=='.' && s[1]=='/')
- return 0;
- if(s[0]=='.' && s[1]=='.' && s[2]=='/')
- return 0;
- return 1;
-}
-
-/* adapted from mail. not entirely free of details from that environment */
-void
-execproc(void *v)
-{
- struct Exec *e;
- char *cmd, **av;
- Channel *cpid;
-
- e = v;
- rfork(RFCFDG|RFNOTEG);
- av = e->argv;
- close(0);
- open("/dev/cons", OREAD);
- close(1);
- open("/dev/cons", OWRITE);
- dup(1, 2);
- cpid = e->cpid;
- free(e);
- procexec(cpid, av[0], av);
- if(lookinbin(av[0])){
- cmd = estrstrdup("/bin/", av[0]);
- procexec(cpid, cmd, av);
- }
- error("can't exec %s: %r", av[0]);
-}
-
-void
-startcmd(char *argv[], int *notepg)
-{
- struct Exec *e;
- Channel *cpid;
- char buf[64];
- int pid;
-
- e = emalloc(sizeof(struct Exec));
- e->argv = argv;
- cpid = chancreate(sizeof(ulong), 0);
- e->cpid = cpid;
- sprint(buf, "/mnt/wsys/%d", win->id);
- bind(buf, "/dev/acme", MREPL);
- proccreate(execproc, e, EXECSTACK);
- do
- pid = recvul(cpid);
- while(pid == -1);
- sprint(buf, "/proc/%d/notepg", pid);
- *notepg = open(buf, OWRITE);
-}