|
|
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.