Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}