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