Subversion Repositories planix.SVN

Rev

Details | 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
Channel *fschan;
9
Channel *writechan;
10
 
11
static File *devcons, *devnew;
12
 
13
static void
14
fsread(Req *r)
15
{
16
	Fsevent e;
17
 
18
	if(r->fid->file == devnew){
19
		if(r->fid->aux==nil){
20
			respond(r, "phase error");
21
			return;
22
		}
23
		readstr(r, r->fid->aux);
24
		respond(r, nil);
25
		return;
26
	}
27
 
28
	assert(r->fid->file == devcons);
29
	e.type = 'r';
30
	e.r = r;
31
	send(fschan, &e);
32
}
33
 
34
static void
35
fsflush(Req *r)
36
{
37
	Fsevent e;
38
 
39
	e.type = 'f';
40
	e.r = r;
41
	send(fschan, &e);
42
}
43
 
44
static void
45
fswrite(Req *r)
46
{
47
	static Event *e[4];
48
	Event *ep;
49
	int i, j, ei, nb, wid, pid;
50
	Rune rune;
51
	char *s;
52
	char tmp[UTFmax], *t;
53
	static int n, partial;
54
 
55
	if(r->fid->file == devnew){
56
		if(r->fid->aux){
57
			respond(r, "already created a window");
58
			return;
59
		}
60
		s = emalloc(r->ifcall.count+1);
61
		memmove(s, r->ifcall.data, r->ifcall.count);
62
		s[r->ifcall.count] = 0;
63
		pid = strtol(s, &t, 0);
64
		if(*t==' ')
65
			t++;
66
		i = newpipewin(pid, t);
67
		free(s);
68
		s = emalloc(32);
69
		sprint(s, "%lud", (ulong)i);
70
		r->fid->aux = s;
71
		r->ofcall.count = r->ifcall.count;
72
		respond(r, nil);
73
		return;
74
	}
75
 
76
	assert(r->fid->file == devcons);
77
 
78
	if(e[0] == nil){
79
		for(i=0; i<nelem(e); i++){
80
			e[i] = emalloc(sizeof(Event));
81
			e[i]->c1 = 'S';
82
		}
83
	}
84
 
85
	ep = e[n];
86
	n = (n+1)%nelem(e);
87
	assert(r->ifcall.count <= 8192);	/* is this guaranteed by lib9p? */
88
	nb = r->ifcall.count;
89
	memmove(ep->b+partial, r->ifcall.data, nb);
90
	nb += partial;
91
	ep->b[nb] = '\0';
92
	if(strlen(ep->b) < nb){	/* nulls in data */
93
		t = ep->b;
94
		for(i=j=0; i<nb; i++)
95
			if(ep->b[i] != '\0')
96
				t[j++] = ep->b[i];
97
		nb = j;
98
		t[j] = '\0';
99
	}
100
	ei = nb>8192? 8192 : nb;
101
	/* process bytes into runes, transferring terminal partial runes into next buffer */
102
	for(i=j=0; i<ei && fullrune(ep->b+i, ei-i); i+=wid,j++)
103
		wid = chartorune(&rune, ep->b+i);
104
	memmove(tmp, ep->b+i, nb-i);
105
	partial = nb-i;
106
	ep->nb = i;
107
	ep->nr = j;
108
	ep->b[i] = '\0';
109
	if(i != 0){
110
		sendp(win->cevent, ep);
111
		recvp(writechan);
112
	}
113
	partial = nb-i;
114
	memmove(e[n]->b, tmp, partial);
115
	r->ofcall.count = r->ifcall.count;
116
	respond(r, nil);
117
}
118
 
119
void
120
fsdestroyfid(Fid *fid)
121
{
122
	if(fid->aux)
123
		free(fid->aux);
124
}
125
 
126
Srv fs = {
127
.read=	fsread,
128
.write=	fswrite,
129
.flush=	fsflush,
130
.destroyfid=	fsdestroyfid,
131
.leavefdsopen=	1,
132
};
133
 
134
void
135
mountcons(void)
136
{
137
	fschan = chancreate(sizeof(Fsevent), 0);
138
	writechan = chancreate(sizeof(void*), 0);
139
	fs.tree = alloctree("win", "win", DMDIR|0555, nil);
140
	devcons = createfile(fs.tree->root, "cons", "win", 0666, nil);
141
	if(devcons == nil)
142
		sysfatal("creating /dev/cons: %r");
143
	devnew = createfile(fs.tree->root, "wnew", "win", 0666, nil);
144
	if(devnew == nil)
145
		sysfatal("creating /dev/wnew: %r");
146
	threadpostmountsrv(&fs, nil, "/dev", MBEFORE);
147
}