|
|
1.1 root 1: /*
2: * connector l.d.: install on a stream-mounted file.
3: * Opens on the file send new, unique pipe to the
4: * server and return the other end of the pipe.
5: */
6:
7: #include "../h/param.h"
8: #include "../h/systm.h"
9: #include "../h/stream.h"
10: #include "../h/filio.h"
11: #include "../h/map.h"
12: #include "../h/buf.h"
13: /*#include "../h/ubavar.h"*/
14: #include "../h/conf.h"
15: #include "../h/file.h"
16: #include "../h/inode.h"
17: #include "../h/ttyio.h"
18: #include "../h/ttyld.h"
19: #include "connld.h"
20:
21:
22: #define STIPRI 28
23: int connopen(), connput(), nulldev(), conngput();
24:
25: static struct qinit connrinit = { connput, 0, connopen, nulldev, 0, 0 };
26: static struct qinit connwinit = { connput, 0, connopen, nulldev, 0, 0 };
27: struct streamtab connldinfo = { &connrinit, &connwinit };
28:
29: static struct qinit connrgrab = { conngput, 0, nulldev, nulldev, 0, 0 };
30: static struct qinit connwgrab = { connput, 0, nulldev, nulldev, 0, 0 };
31: struct streamtab connginfo = { &connrgrab, &connwgrab };
32:
33: connopen(q, dev)
34: register struct queue *q;
35: {
36: struct inode *ip1, *ip2;
37: register struct file *fp, *nfp;
38: register s;
39: register struct block *bp;
40: register struct queue *nq;
41: register ioc;
42:
43: if ((int)q->ptr == 0) { /* the open on push does nothing */
44: q->ptr = (caddr_t)1;
45: return(1);
46: }
47: /* make pipe, send one end to other side */
48: if ((fp = allocfile()) == NULL)
49: return(0);
50: if (makepipe(&ip1, &ip2)==0) {
51: fp->f_count = 0;
52: return(0);
53: }
54: fp->f_inode = ip2;
55: fp->f_flag = FREAD|FWRITE;
56: fp->f_count--;
57: nq = RD(ip1->i_sptr->wrq);
58: if (sndfile(WR(q), fp)==0) {
59: stclose(ip1, 1);
60: iput(ip1);
61: stclose(ip2, 1);
62: iput(ip2);
63: return(0);
64: }
65: if (qattach(&connginfo, nq, (dev_t)0)==0) {
66: stclose(ip1, 1);
67: iput(ip1);
68: return(0);
69: }
70: nq = backq(nq);
71: /* wait for reply */
72: s = spl5();
73: while ((bp = getq(nq))==NULL) {
74: if (tsleep((caddr_t)nq, STIPRI, 0) != TS_OK) {
75: stclose(ip1, 1);
76: iput(ip1);
77: return(0);
78: }
79: }
80: splx(s);
81:
82: switch(bp->type) {
83:
84: case M_HANGUP:
85: freeb(bp);
86: stclose(ip1, 1);
87: iput(ip1);
88: return(0);
89:
90: case M_PASS: /* accept, and provide a newer file */
91: stclose(ip1, 1);
92: iput(ip1);
93: nfp = ((struct kpassfd *)bp->rptr)->f.fp;
94: ip1 = nfp->f_inode;
95: ip1->i_count++;
96: closef(nfp);
97: return((long)ip1);
98:
99: case M_IOCTL:
100: ioc = ((union stmsg *)bp->rptr)->ioc0.com;
101: if (ioc==FIOACCEPT || ioc==FIOREJECT) {
102: bp->type = M_IOCACK;
103: bp->wptr = bp->rptr;
104: qreply(nq, bp);
105: if (ioc==FIOREJECT) {
106: stclose(ip1, 1);
107: iput(ip1);
108: return(0);
109: }
110: while (bp = getq(nq))
111: (*nq->next->qinfo->putp)(nq->next, bp);
112: qdetach(nq, 1);
113: return((long)ip1);
114: }
115: default: /* flow through */
116: (*nq->next->qinfo->putp)(nq->next, bp);
117: while (bp = getq(nq))
118: (*nq->next->qinfo->putp)(nq->next, bp);
119: qdetach(nq, 1);
120: return((long)ip1);
121: }
122: }
123:
124: connput(q, bp)
125: register struct queue *q;
126: register struct block *bp;
127: {
128: switch (bp->type) {
129:
130: case M_HANGUP:
131: case M_IOCTL:
132: case M_IOCACK:
133: case M_IOCNAK:
134: case M_PASS:
135: (*q->next->qinfo->putp)(q->next, bp);
136: return;
137: }
138: freeb(bp);
139: }
140:
141: conngput(q, bp)
142: register struct queue *q;
143: register struct block *bp;
144: {
145: putq(q, bp);
146: wakeup((caddr_t)q);
147: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.