]> git.lizzy.rs Git - plan9front.git/blob - acme/bin/source/win/pipe.c
fill /acme
[plan9front.git] / acme / bin / source / win / pipe.c
1 #include <u.h>
2 #include <libc.h>
3 #include <fcall.h>
4 #include <thread.h>
5 #include <9p.h>
6 #include "dat.h"
7
8 typedef struct Wpid Wpid;
9 struct Wpid
10 {
11         int             pid;
12         Window  *w;
13         Wpid            *next;
14 };
15
16 void    pipectl(void*);
17
18 int     pipefd;
19 Wpid    *wpid;
20 int     snarffd;
21 Channel *newpipechan;
22
23 int
24 newpipewin(int pid, char *p)
25 {
26         int id;
27         Window *w;
28         Wpid *wp;
29
30         w = newwindow();
31         winname(w, p);
32         wintagwrite(w, "Send ", 5);
33         wp = emalloc(sizeof(Wpid));
34         wp->pid = pid;
35         wp->w = w;
36         wp->next = wpid;        /* BUG: this happens in fsread proc (we don't use wpid, so it's okay) */
37         wpid = wp;
38         id = w->id;
39         sendp(newpipechan, w);
40         return id;
41 }
42
43 int
44 pipecommand(Window *w, char *s)
45 {
46         ulong q0, q1;
47         char tmp[32], *t;
48         int n, k;
49
50         while(*s==' ' || *s=='\t' || *s=='\n')
51                 s++;
52         if(strcmp(s, "Delete")==0){
53                 windel(w, 1);
54                 threadexits(nil);
55                 return 1;
56         }
57         if(strcmp(s, "Del")==0){
58                 if(windel(w, 0))
59                         threadexits(nil);
60                 return 1;
61         }
62         if(strcmp(s, "Send") == 0){
63                 if(w->addr < 0)
64                         w->addr = winopenfile(w, "addr");
65                 ctlprint(w->ctl, "addr=dot\n");
66                 seek(w->addr, 0UL, 0);
67                 if(read(w->addr, tmp, 2*12) == 2*12){
68                         q0 = atol(tmp+0*12);
69                         q1 = atol(tmp+1*12);
70                         if(q0 == q1){
71                                 t = nil;
72                                 k = 0;
73                                 if(snarffd > 0){
74                                         seek(0, snarffd, 0);
75                                         for(;;){
76                                                 t = realloc(t, k+8192+2);
77                                                 if(t == nil)
78                                                         error("alloc failed: %r\n");
79                                                 n = read(snarffd, t+k, 8192);
80                                                 if(n <= 0)
81                                                         break;
82                                                 k += n;
83                                         }
84                                         t[k] = 0;
85                                 }
86                         }else{
87                                 t = emalloc((q1-q0)*UTFmax+2);
88                                 winread(w, q0, q1, t);
89                                 k = strlen(t);
90                         }
91                         if(t!=nil && t[0]!='\0'){
92                                 if(t[k-1]!='\n' && t[k-1]!='\004'){
93                                         t[k++] = '\n';
94                                         t[k] = '\0';
95                                 }
96                                 sendit(t);
97                         }
98                         free(t);
99                 }
100                 return 1;
101         }
102         return 0;
103 }
104
105 void
106 pipectl(void *v)
107 {
108         Window *w;
109         Event *e;
110
111         w = v;
112         proccreate(wineventproc, w, STACK);
113
114         windormant(w);
115         winsetaddr(w, "0", 0);
116         for(;;){
117                 e = recvp(w->cevent);
118                 switch(e->c1){
119                 default:
120                 Unknown:
121                         fprint(2, "unknown message %c%c\n", e->c1, e->c2);
122                         break;
123
124                 case 'E':       /* write to body; can't affect us */
125                         break;
126         
127                 case 'F':       /* generated by our actions; ignore */
128                         break;
129         
130                 case 'K':       /* ignore */
131                         break;
132         
133                 case 'M':
134                         switch(e->c2){
135                         case 'x':
136                         case 'X':
137                                 execevent(w, e, pipecommand);
138                                 break;
139         
140                         case 'l':       /* reflect all searches back to acme */
141                         case 'L':
142                                 if(e->flag & 2)
143                                         recvp(w->cevent);
144                                 winwriteevent(w, e);
145                                 break;
146         
147                         case 'I':       /* modify away; we don't care */
148                         case 'i':
149                         case 'D':
150                         case 'd':
151                                 break;
152         
153                         default:
154                                 goto Unknown;
155                         }
156                 }
157         }
158 }
159
160 void
161 newpipethread(void*)
162 {
163         Window *w;
164
165         while(w = recvp(newpipechan))
166                 threadcreate(pipectl, w, STACK);
167 }
168
169 void
170 startpipe(void)
171 {
172         newpipechan = chancreate(sizeof(Window*), 0);
173         threadcreate(newpipethread, nil, STACK);
174         snarffd = open("/dev/snarf", OREAD|OCEXEC);
175 }