1*8ccd4a63SDavid du Colombier #include "u.h"
2*8ccd4a63SDavid du Colombier #include "lib.h"
3*8ccd4a63SDavid du Colombier #include "dat.h"
4*8ccd4a63SDavid du Colombier #include "fns.h"
5*8ccd4a63SDavid du Colombier #include "error.h"
6*8ccd4a63SDavid du Colombier
7*8ccd4a63SDavid du Colombier #include "netif.h"
8*8ccd4a63SDavid du Colombier
9*8ccd4a63SDavid du Colombier typedef struct Pipe Pipe;
10*8ccd4a63SDavid du Colombier struct Pipe
11*8ccd4a63SDavid du Colombier {
12*8ccd4a63SDavid du Colombier QLock lk;
13*8ccd4a63SDavid du Colombier Pipe *next;
14*8ccd4a63SDavid du Colombier int ref;
15*8ccd4a63SDavid du Colombier ulong path;
16*8ccd4a63SDavid du Colombier Queue *q[2];
17*8ccd4a63SDavid du Colombier int qref[2];
18*8ccd4a63SDavid du Colombier };
19*8ccd4a63SDavid du Colombier
20*8ccd4a63SDavid du Colombier struct
21*8ccd4a63SDavid du Colombier {
22*8ccd4a63SDavid du Colombier Lock lk;
23*8ccd4a63SDavid du Colombier ulong path;
24*8ccd4a63SDavid du Colombier } pipealloc;
25*8ccd4a63SDavid du Colombier
26*8ccd4a63SDavid du Colombier enum
27*8ccd4a63SDavid du Colombier {
28*8ccd4a63SDavid du Colombier Qdir,
29*8ccd4a63SDavid du Colombier Qdata0,
30*8ccd4a63SDavid du Colombier Qdata1,
31*8ccd4a63SDavid du Colombier };
32*8ccd4a63SDavid du Colombier
33*8ccd4a63SDavid du Colombier Dirtab pipedir[] =
34*8ccd4a63SDavid du Colombier {
35*8ccd4a63SDavid du Colombier ".", {Qdir,0,QTDIR}, 0, DMDIR|0500,
36*8ccd4a63SDavid du Colombier "data", {Qdata0}, 0, 0600,
37*8ccd4a63SDavid du Colombier "data1", {Qdata1}, 0, 0600,
38*8ccd4a63SDavid du Colombier };
39*8ccd4a63SDavid du Colombier #define NPIPEDIR 3
40*8ccd4a63SDavid du Colombier
41*8ccd4a63SDavid du Colombier static void
pipeinit(void)42*8ccd4a63SDavid du Colombier pipeinit(void)
43*8ccd4a63SDavid du Colombier {
44*8ccd4a63SDavid du Colombier if(conf.pipeqsize == 0){
45*8ccd4a63SDavid du Colombier if(conf.nmach > 1)
46*8ccd4a63SDavid du Colombier conf.pipeqsize = 256*1024;
47*8ccd4a63SDavid du Colombier else
48*8ccd4a63SDavid du Colombier conf.pipeqsize = 32*1024;
49*8ccd4a63SDavid du Colombier }
50*8ccd4a63SDavid du Colombier }
51*8ccd4a63SDavid du Colombier
52*8ccd4a63SDavid du Colombier /*
53*8ccd4a63SDavid du Colombier * create a pipe, no streams are created until an open
54*8ccd4a63SDavid du Colombier */
55*8ccd4a63SDavid du Colombier static Chan*
pipeattach(char * spec)56*8ccd4a63SDavid du Colombier pipeattach(char *spec)
57*8ccd4a63SDavid du Colombier {
58*8ccd4a63SDavid du Colombier Pipe *p;
59*8ccd4a63SDavid du Colombier Chan *c;
60*8ccd4a63SDavid du Colombier
61*8ccd4a63SDavid du Colombier c = devattach('|', spec);
62*8ccd4a63SDavid du Colombier p = malloc(sizeof(Pipe));
63*8ccd4a63SDavid du Colombier if(p == 0)
64*8ccd4a63SDavid du Colombier exhausted("memory");
65*8ccd4a63SDavid du Colombier p->ref = 1;
66*8ccd4a63SDavid du Colombier
67*8ccd4a63SDavid du Colombier p->q[0] = qopen(conf.pipeqsize, 0, 0, 0);
68*8ccd4a63SDavid du Colombier if(p->q[0] == 0){
69*8ccd4a63SDavid du Colombier free(p);
70*8ccd4a63SDavid du Colombier exhausted("memory");
71*8ccd4a63SDavid du Colombier }
72*8ccd4a63SDavid du Colombier p->q[1] = qopen(conf.pipeqsize, 0, 0, 0);
73*8ccd4a63SDavid du Colombier if(p->q[1] == 0){
74*8ccd4a63SDavid du Colombier free(p->q[0]);
75*8ccd4a63SDavid du Colombier free(p);
76*8ccd4a63SDavid du Colombier exhausted("memory");
77*8ccd4a63SDavid du Colombier }
78*8ccd4a63SDavid du Colombier
79*8ccd4a63SDavid du Colombier lock(&pipealloc.lk);
80*8ccd4a63SDavid du Colombier p->path = ++pipealloc.path;
81*8ccd4a63SDavid du Colombier unlock(&pipealloc.lk);
82*8ccd4a63SDavid du Colombier
83*8ccd4a63SDavid du Colombier mkqid(&c->qid, NETQID(2*p->path, Qdir), 0, QTDIR);
84*8ccd4a63SDavid du Colombier c->aux = p;
85*8ccd4a63SDavid du Colombier c->dev = 0;
86*8ccd4a63SDavid du Colombier return c;
87*8ccd4a63SDavid du Colombier }
88*8ccd4a63SDavid du Colombier
89*8ccd4a63SDavid du Colombier static int
pipegen(Chan * c,char * name,Dirtab * tab,int ntab,int i,Dir * dp)90*8ccd4a63SDavid du Colombier pipegen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp)
91*8ccd4a63SDavid du Colombier {
92*8ccd4a63SDavid du Colombier Qid q;
93*8ccd4a63SDavid du Colombier int len;
94*8ccd4a63SDavid du Colombier Pipe *p;
95*8ccd4a63SDavid du Colombier
96*8ccd4a63SDavid du Colombier USED(name);
97*8ccd4a63SDavid du Colombier
98*8ccd4a63SDavid du Colombier if(i == DEVDOTDOT){
99*8ccd4a63SDavid du Colombier devdir(c, c->qid, "#|", 0, eve, DMDIR|0555, dp);
100*8ccd4a63SDavid du Colombier return 1;
101*8ccd4a63SDavid du Colombier }
102*8ccd4a63SDavid du Colombier i++; /* skip . */
103*8ccd4a63SDavid du Colombier if(tab==0 || i>=ntab)
104*8ccd4a63SDavid du Colombier return -1;
105*8ccd4a63SDavid du Colombier
106*8ccd4a63SDavid du Colombier tab += i;
107*8ccd4a63SDavid du Colombier p = c->aux;
108*8ccd4a63SDavid du Colombier switch((ulong)tab->qid.path){
109*8ccd4a63SDavid du Colombier case Qdata0:
110*8ccd4a63SDavid du Colombier len = qlen(p->q[0]);
111*8ccd4a63SDavid du Colombier break;
112*8ccd4a63SDavid du Colombier case Qdata1:
113*8ccd4a63SDavid du Colombier len = qlen(p->q[1]);
114*8ccd4a63SDavid du Colombier break;
115*8ccd4a63SDavid du Colombier default:
116*8ccd4a63SDavid du Colombier len = tab->length;
117*8ccd4a63SDavid du Colombier break;
118*8ccd4a63SDavid du Colombier }
119*8ccd4a63SDavid du Colombier mkqid(&q, NETQID(NETID(c->qid.path), tab->qid.path), 0, QTFILE);
120*8ccd4a63SDavid du Colombier devdir(c, q, tab->name, len, eve, tab->perm, dp);
121*8ccd4a63SDavid du Colombier return 1;
122*8ccd4a63SDavid du Colombier }
123*8ccd4a63SDavid du Colombier
124*8ccd4a63SDavid du Colombier
125*8ccd4a63SDavid du Colombier static Walkqid*
pipewalk(Chan * c,Chan * nc,char ** name,int nname)126*8ccd4a63SDavid du Colombier pipewalk(Chan *c, Chan *nc, char **name, int nname)
127*8ccd4a63SDavid du Colombier {
128*8ccd4a63SDavid du Colombier Walkqid *wq;
129*8ccd4a63SDavid du Colombier Pipe *p;
130*8ccd4a63SDavid du Colombier
131*8ccd4a63SDavid du Colombier wq = devwalk(c, nc, name, nname, pipedir, NPIPEDIR, pipegen);
132*8ccd4a63SDavid du Colombier if(wq != nil && wq->clone != nil && wq->clone != c){
133*8ccd4a63SDavid du Colombier p = c->aux;
134*8ccd4a63SDavid du Colombier qlock(&p->lk);
135*8ccd4a63SDavid du Colombier p->ref++;
136*8ccd4a63SDavid du Colombier if(c->flag & COPEN){
137*8ccd4a63SDavid du Colombier print("channel open in pipewalk\n");
138*8ccd4a63SDavid du Colombier switch(NETTYPE(c->qid.path)){
139*8ccd4a63SDavid du Colombier case Qdata0:
140*8ccd4a63SDavid du Colombier p->qref[0]++;
141*8ccd4a63SDavid du Colombier break;
142*8ccd4a63SDavid du Colombier case Qdata1:
143*8ccd4a63SDavid du Colombier p->qref[1]++;
144*8ccd4a63SDavid du Colombier break;
145*8ccd4a63SDavid du Colombier }
146*8ccd4a63SDavid du Colombier }
147*8ccd4a63SDavid du Colombier qunlock(&p->lk);
148*8ccd4a63SDavid du Colombier }
149*8ccd4a63SDavid du Colombier return wq;
150*8ccd4a63SDavid du Colombier }
151*8ccd4a63SDavid du Colombier
152*8ccd4a63SDavid du Colombier static int
pipestat(Chan * c,uchar * db,int n)153*8ccd4a63SDavid du Colombier pipestat(Chan *c, uchar *db, int n)
154*8ccd4a63SDavid du Colombier {
155*8ccd4a63SDavid du Colombier Pipe *p;
156*8ccd4a63SDavid du Colombier Dir dir;
157*8ccd4a63SDavid du Colombier
158*8ccd4a63SDavid du Colombier p = c->aux;
159*8ccd4a63SDavid du Colombier
160*8ccd4a63SDavid du Colombier switch(NETTYPE(c->qid.path)){
161*8ccd4a63SDavid du Colombier case Qdir:
162*8ccd4a63SDavid du Colombier devdir(c, c->qid, ".", 0, eve, DMDIR|0555, &dir);
163*8ccd4a63SDavid du Colombier break;
164*8ccd4a63SDavid du Colombier case Qdata0:
165*8ccd4a63SDavid du Colombier devdir(c, c->qid, "data", qlen(p->q[0]), eve, 0600, &dir);
166*8ccd4a63SDavid du Colombier break;
167*8ccd4a63SDavid du Colombier case Qdata1:
168*8ccd4a63SDavid du Colombier devdir(c, c->qid, "data1", qlen(p->q[1]), eve, 0600, &dir);
169*8ccd4a63SDavid du Colombier break;
170*8ccd4a63SDavid du Colombier default:
171*8ccd4a63SDavid du Colombier panic("pipestat");
172*8ccd4a63SDavid du Colombier }
173*8ccd4a63SDavid du Colombier n = convD2M(&dir, db, n);
174*8ccd4a63SDavid du Colombier if(n < BIT16SZ)
175*8ccd4a63SDavid du Colombier error(Eshortstat);
176*8ccd4a63SDavid du Colombier return n;
177*8ccd4a63SDavid du Colombier }
178*8ccd4a63SDavid du Colombier
179*8ccd4a63SDavid du Colombier /*
180*8ccd4a63SDavid du Colombier * if the stream doesn't exist, create it
181*8ccd4a63SDavid du Colombier */
182*8ccd4a63SDavid du Colombier static Chan*
pipeopen(Chan * c,int omode)183*8ccd4a63SDavid du Colombier pipeopen(Chan *c, int omode)
184*8ccd4a63SDavid du Colombier {
185*8ccd4a63SDavid du Colombier Pipe *p;
186*8ccd4a63SDavid du Colombier
187*8ccd4a63SDavid du Colombier if(c->qid.type & QTDIR){
188*8ccd4a63SDavid du Colombier if(omode != OREAD)
189*8ccd4a63SDavid du Colombier error(Ebadarg);
190*8ccd4a63SDavid du Colombier c->mode = omode;
191*8ccd4a63SDavid du Colombier c->flag |= COPEN;
192*8ccd4a63SDavid du Colombier c->offset = 0;
193*8ccd4a63SDavid du Colombier return c;
194*8ccd4a63SDavid du Colombier }
195*8ccd4a63SDavid du Colombier
196*8ccd4a63SDavid du Colombier p = c->aux;
197*8ccd4a63SDavid du Colombier qlock(&p->lk);
198*8ccd4a63SDavid du Colombier switch(NETTYPE(c->qid.path)){
199*8ccd4a63SDavid du Colombier case Qdata0:
200*8ccd4a63SDavid du Colombier p->qref[0]++;
201*8ccd4a63SDavid du Colombier break;
202*8ccd4a63SDavid du Colombier case Qdata1:
203*8ccd4a63SDavid du Colombier p->qref[1]++;
204*8ccd4a63SDavid du Colombier break;
205*8ccd4a63SDavid du Colombier }
206*8ccd4a63SDavid du Colombier qunlock(&p->lk);
207*8ccd4a63SDavid du Colombier
208*8ccd4a63SDavid du Colombier c->mode = openmode(omode);
209*8ccd4a63SDavid du Colombier c->flag |= COPEN;
210*8ccd4a63SDavid du Colombier c->offset = 0;
211*8ccd4a63SDavid du Colombier c->iounit = qiomaxatomic;
212*8ccd4a63SDavid du Colombier return c;
213*8ccd4a63SDavid du Colombier }
214*8ccd4a63SDavid du Colombier
215*8ccd4a63SDavid du Colombier static void
pipeclose(Chan * c)216*8ccd4a63SDavid du Colombier pipeclose(Chan *c)
217*8ccd4a63SDavid du Colombier {
218*8ccd4a63SDavid du Colombier Pipe *p;
219*8ccd4a63SDavid du Colombier
220*8ccd4a63SDavid du Colombier p = c->aux;
221*8ccd4a63SDavid du Colombier qlock(&p->lk);
222*8ccd4a63SDavid du Colombier
223*8ccd4a63SDavid du Colombier if(c->flag & COPEN){
224*8ccd4a63SDavid du Colombier /*
225*8ccd4a63SDavid du Colombier * closing either side hangs up the stream
226*8ccd4a63SDavid du Colombier */
227*8ccd4a63SDavid du Colombier switch(NETTYPE(c->qid.path)){
228*8ccd4a63SDavid du Colombier case Qdata0:
229*8ccd4a63SDavid du Colombier p->qref[0]--;
230*8ccd4a63SDavid du Colombier if(p->qref[0] == 0){
231*8ccd4a63SDavid du Colombier qhangup(p->q[1], 0);
232*8ccd4a63SDavid du Colombier qclose(p->q[0]);
233*8ccd4a63SDavid du Colombier }
234*8ccd4a63SDavid du Colombier break;
235*8ccd4a63SDavid du Colombier case Qdata1:
236*8ccd4a63SDavid du Colombier p->qref[1]--;
237*8ccd4a63SDavid du Colombier if(p->qref[1] == 0){
238*8ccd4a63SDavid du Colombier qhangup(p->q[0], 0);
239*8ccd4a63SDavid du Colombier qclose(p->q[1]);
240*8ccd4a63SDavid du Colombier }
241*8ccd4a63SDavid du Colombier break;
242*8ccd4a63SDavid du Colombier }
243*8ccd4a63SDavid du Colombier }
244*8ccd4a63SDavid du Colombier
245*8ccd4a63SDavid du Colombier
246*8ccd4a63SDavid du Colombier /*
247*8ccd4a63SDavid du Colombier * if both sides are closed, they are reusable
248*8ccd4a63SDavid du Colombier */
249*8ccd4a63SDavid du Colombier if(p->qref[0] == 0 && p->qref[1] == 0){
250*8ccd4a63SDavid du Colombier qreopen(p->q[0]);
251*8ccd4a63SDavid du Colombier qreopen(p->q[1]);
252*8ccd4a63SDavid du Colombier }
253*8ccd4a63SDavid du Colombier
254*8ccd4a63SDavid du Colombier /*
255*8ccd4a63SDavid du Colombier * free the structure on last close
256*8ccd4a63SDavid du Colombier */
257*8ccd4a63SDavid du Colombier p->ref--;
258*8ccd4a63SDavid du Colombier if(p->ref == 0){
259*8ccd4a63SDavid du Colombier qunlock(&p->lk);
260*8ccd4a63SDavid du Colombier free(p->q[0]);
261*8ccd4a63SDavid du Colombier free(p->q[1]);
262*8ccd4a63SDavid du Colombier free(p);
263*8ccd4a63SDavid du Colombier } else
264*8ccd4a63SDavid du Colombier qunlock(&p->lk);
265*8ccd4a63SDavid du Colombier }
266*8ccd4a63SDavid du Colombier
267*8ccd4a63SDavid du Colombier static long
piperead(Chan * c,void * va,long n,vlong offset)268*8ccd4a63SDavid du Colombier piperead(Chan *c, void *va, long n, vlong offset)
269*8ccd4a63SDavid du Colombier {
270*8ccd4a63SDavid du Colombier Pipe *p;
271*8ccd4a63SDavid du Colombier
272*8ccd4a63SDavid du Colombier USED(offset);
273*8ccd4a63SDavid du Colombier
274*8ccd4a63SDavid du Colombier p = c->aux;
275*8ccd4a63SDavid du Colombier
276*8ccd4a63SDavid du Colombier switch(NETTYPE(c->qid.path)){
277*8ccd4a63SDavid du Colombier case Qdir:
278*8ccd4a63SDavid du Colombier return devdirread(c, va, n, pipedir, NPIPEDIR, pipegen);
279*8ccd4a63SDavid du Colombier case Qdata0:
280*8ccd4a63SDavid du Colombier return qread(p->q[0], va, n);
281*8ccd4a63SDavid du Colombier case Qdata1:
282*8ccd4a63SDavid du Colombier return qread(p->q[1], va, n);
283*8ccd4a63SDavid du Colombier default:
284*8ccd4a63SDavid du Colombier panic("piperead");
285*8ccd4a63SDavid du Colombier }
286*8ccd4a63SDavid du Colombier return -1; /* not reached */
287*8ccd4a63SDavid du Colombier }
288*8ccd4a63SDavid du Colombier
289*8ccd4a63SDavid du Colombier static Block*
pipebread(Chan * c,long n,ulong offset)290*8ccd4a63SDavid du Colombier pipebread(Chan *c, long n, ulong offset)
291*8ccd4a63SDavid du Colombier {
292*8ccd4a63SDavid du Colombier Pipe *p;
293*8ccd4a63SDavid du Colombier
294*8ccd4a63SDavid du Colombier p = c->aux;
295*8ccd4a63SDavid du Colombier
296*8ccd4a63SDavid du Colombier switch(NETTYPE(c->qid.path)){
297*8ccd4a63SDavid du Colombier case Qdata0:
298*8ccd4a63SDavid du Colombier return qbread(p->q[0], n);
299*8ccd4a63SDavid du Colombier case Qdata1:
300*8ccd4a63SDavid du Colombier return qbread(p->q[1], n);
301*8ccd4a63SDavid du Colombier }
302*8ccd4a63SDavid du Colombier
303*8ccd4a63SDavid du Colombier return devbread(c, n, offset);
304*8ccd4a63SDavid du Colombier }
305*8ccd4a63SDavid du Colombier
306*8ccd4a63SDavid du Colombier /*
307*8ccd4a63SDavid du Colombier * a write to a closed pipe causes a note to be sent to
308*8ccd4a63SDavid du Colombier * the process.
309*8ccd4a63SDavid du Colombier */
310*8ccd4a63SDavid du Colombier static long
pipewrite(Chan * c,void * va,long n,vlong offset)311*8ccd4a63SDavid du Colombier pipewrite(Chan *c, void *va, long n, vlong offset)
312*8ccd4a63SDavid du Colombier {
313*8ccd4a63SDavid du Colombier Pipe *p;
314*8ccd4a63SDavid du Colombier
315*8ccd4a63SDavid du Colombier USED(offset);
316*8ccd4a63SDavid du Colombier if(!islo())
317*8ccd4a63SDavid du Colombier print("pipewrite hi %lux\n", getcallerpc(&c));
318*8ccd4a63SDavid du Colombier
319*8ccd4a63SDavid du Colombier if(waserror()) {
320*8ccd4a63SDavid du Colombier /* avoid notes when pipe is a mounted queue */
321*8ccd4a63SDavid du Colombier if((c->flag & CMSG) == 0)
322*8ccd4a63SDavid du Colombier postnote(up, 1, "sys: write on closed pipe", NUser);
323*8ccd4a63SDavid du Colombier nexterror();
324*8ccd4a63SDavid du Colombier }
325*8ccd4a63SDavid du Colombier
326*8ccd4a63SDavid du Colombier p = c->aux;
327*8ccd4a63SDavid du Colombier
328*8ccd4a63SDavid du Colombier switch(NETTYPE(c->qid.path)){
329*8ccd4a63SDavid du Colombier case Qdata0:
330*8ccd4a63SDavid du Colombier n = qwrite(p->q[1], va, n);
331*8ccd4a63SDavid du Colombier break;
332*8ccd4a63SDavid du Colombier
333*8ccd4a63SDavid du Colombier case Qdata1:
334*8ccd4a63SDavid du Colombier n = qwrite(p->q[0], va, n);
335*8ccd4a63SDavid du Colombier break;
336*8ccd4a63SDavid du Colombier
337*8ccd4a63SDavid du Colombier default:
338*8ccd4a63SDavid du Colombier panic("pipewrite");
339*8ccd4a63SDavid du Colombier }
340*8ccd4a63SDavid du Colombier
341*8ccd4a63SDavid du Colombier poperror();
342*8ccd4a63SDavid du Colombier return n;
343*8ccd4a63SDavid du Colombier }
344*8ccd4a63SDavid du Colombier
345*8ccd4a63SDavid du Colombier static long
pipebwrite(Chan * c,Block * bp,ulong offset)346*8ccd4a63SDavid du Colombier pipebwrite(Chan *c, Block *bp, ulong offset)
347*8ccd4a63SDavid du Colombier {
348*8ccd4a63SDavid du Colombier long n;
349*8ccd4a63SDavid du Colombier Pipe *p;
350*8ccd4a63SDavid du Colombier
351*8ccd4a63SDavid du Colombier USED(offset);
352*8ccd4a63SDavid du Colombier
353*8ccd4a63SDavid du Colombier if(waserror()) {
354*8ccd4a63SDavid du Colombier /* avoid notes when pipe is a mounted queue */
355*8ccd4a63SDavid du Colombier if((c->flag & CMSG) == 0)
356*8ccd4a63SDavid du Colombier postnote(up, 1, "sys: write on closed pipe", NUser);
357*8ccd4a63SDavid du Colombier nexterror();
358*8ccd4a63SDavid du Colombier }
359*8ccd4a63SDavid du Colombier
360*8ccd4a63SDavid du Colombier p = c->aux;
361*8ccd4a63SDavid du Colombier switch(NETTYPE(c->qid.path)){
362*8ccd4a63SDavid du Colombier case Qdata0:
363*8ccd4a63SDavid du Colombier n = qbwrite(p->q[1], bp);
364*8ccd4a63SDavid du Colombier break;
365*8ccd4a63SDavid du Colombier
366*8ccd4a63SDavid du Colombier case Qdata1:
367*8ccd4a63SDavid du Colombier n = qbwrite(p->q[0], bp);
368*8ccd4a63SDavid du Colombier break;
369*8ccd4a63SDavid du Colombier
370*8ccd4a63SDavid du Colombier default:
371*8ccd4a63SDavid du Colombier n = 0;
372*8ccd4a63SDavid du Colombier panic("pipebwrite");
373*8ccd4a63SDavid du Colombier }
374*8ccd4a63SDavid du Colombier
375*8ccd4a63SDavid du Colombier poperror();
376*8ccd4a63SDavid du Colombier return n;
377*8ccd4a63SDavid du Colombier }
378*8ccd4a63SDavid du Colombier
379*8ccd4a63SDavid du Colombier Dev pipedevtab = {
380*8ccd4a63SDavid du Colombier '|',
381*8ccd4a63SDavid du Colombier "pipe",
382*8ccd4a63SDavid du Colombier
383*8ccd4a63SDavid du Colombier devreset,
384*8ccd4a63SDavid du Colombier pipeinit,
385*8ccd4a63SDavid du Colombier devshutdown,
386*8ccd4a63SDavid du Colombier pipeattach,
387*8ccd4a63SDavid du Colombier pipewalk,
388*8ccd4a63SDavid du Colombier pipestat,
389*8ccd4a63SDavid du Colombier pipeopen,
390*8ccd4a63SDavid du Colombier devcreate,
391*8ccd4a63SDavid du Colombier pipeclose,
392*8ccd4a63SDavid du Colombier piperead,
393*8ccd4a63SDavid du Colombier pipebread,
394*8ccd4a63SDavid du Colombier pipewrite,
395*8ccd4a63SDavid du Colombier pipebwrite,
396*8ccd4a63SDavid du Colombier devremove,
397*8ccd4a63SDavid du Colombier devwstat,
398*8ccd4a63SDavid du Colombier };
399