1*4904Swnj /* uipc_pipe.c 4.1 81/11/15 */ 2*4904Swnj 3*4904Swnj #include "../h/param.h" 4*4904Swnj #include "../h/dir.h" 5*4904Swnj #include "../h/user.h" 6*4904Swnj #include "../h/mbuf.h" 7*4904Swnj #include "../h/protocol.h" 8*4904Swnj #include "../h/protosw.h" 9*4904Swnj #include "../h/socket.h" 10*4904Swnj #include "../h/socketvar.h" 11*4904Swnj #include "../h/inaddr.h" 12*4904Swnj 13*4904Swnj int pi_usrreq(); 14*4904Swnj #define PIPSIZ 4096 15*4904Swnj 16*4904Swnj /* 17*4904Swnj * Code for pipes and other loopback protocols (single machine, that is.) 18*4904Swnj */ 19*4904Swnj struct protosw pipeproto = { 20*4904Swnj SOCK_STREAM, PF_LOCAL, 0, PR_CONNREQUIRED, 21*4904Swnj 0, 0, 0, 0, 22*4904Swnj pi_usrreq, 0, 0, 23*4904Swnj 0, 0, 0, 0 24*4904Swnj }; 25*4904Swnj 26*4904Swnj /* 27*4904Swnj * Connect a pipe from wso to rso. The protocol control block 28*4904Swnj * for a pipe is used to store a pointer to the matching socket. 29*4904Swnj * Each half of the pipe gets half of the buffer space (half send 30*4904Swnj * buffers, half receive buffers). 31*4904Swnj */ 32*4904Swnj pi_connect(wso, rso) 33*4904Swnj struct socket *wso, *rso; 34*4904Swnj { 35*4904Swnj 36*4904Swnj if (m_reserve(PIPSIZ) == 0) { 37*4904Swnj u.u_error = ENOBUFS; 38*4904Swnj return (0); 39*4904Swnj } 40*4904Swnj wso->so_proto = rso->so_proto = &pipeproto; 41*4904Swnj wso->so_pcb = (caddr_t)rso; 42*4904Swnj rso->so_pcb = (caddr_t)wso; 43*4904Swnj wso->so_snd.sb_hiwat = PIPSIZ/2; 44*4904Swnj wso->so_snd.sb_mbcnt = PIPSIZ; 45*4904Swnj wso->so_state |= SS_ISCONNECTED|SS_CANTRCVMORE; 46*4904Swnj rso->so_rcv.sb_hiwat = PIPSIZ/2; 47*4904Swnj rso->so_rcv.sb_mbcnt = PIPSIZ; 48*4904Swnj rso->so_state |= SS_ISCONNECTED|SS_CANTSENDMORE; 49*4904Swnj return (1); 50*4904Swnj } 51*4904Swnj 52*4904Swnj pi_splice(pso, so) 53*4904Swnj struct socket *pso, *so; 54*4904Swnj { 55*4904Swnj 56*4904Swnj if (pso->so_proto != &pipeproto) { 57*4904Swnj struct socket *tso; 58*4904Swnj tso = pso; pso = so; so = tso; 59*4904Swnj } 60*4904Swnj if (pso->so_proto != &pipeproto) 61*4904Swnj return (EOPNOTSUPP); 62*4904Swnj /* check types and buffer space */ 63*4904Swnj /* merge buffers */ 64*4904Swnj return (0); 65*4904Swnj } 66*4904Swnj 67*4904Swnj /* 68*4904Swnj * User requests on pipes and other internally implemented 69*4904Swnj * structures. 70*4904Swnj */ 71*4904Swnj pi_usrreq(so, req, m, addr) 72*4904Swnj struct socket *so; 73*4904Swnj int req; 74*4904Swnj struct mbuf *m; 75*4904Swnj caddr_t addr; 76*4904Swnj { 77*4904Swnj struct socket *so2 = (struct socket *)so->so_pcb; 78*4904Swnj 79*4904Swnj switch (req) { 80*4904Swnj 81*4904Swnj case PRU_ATTACH: 82*4904Swnj case PRU_DETACH: 83*4904Swnj break; 84*4904Swnj 85*4904Swnj case PRU_CONNECT: 86*4904Swnj return (EOPNOTSUPP); 87*4904Swnj 88*4904Swnj case PRU_DISCONNECT: 89*4904Swnj if (so2 == 0) 90*4904Swnj return (ENOTCONN); 91*4904Swnj so->so_pcb = 0; 92*4904Swnj sodetwakeup(so2); 93*4904Swnj so->so_state &= ~SS_ISCONNECTED; 94*4904Swnj break; 95*4904Swnj 96*4904Swnj case PRU_FLUSH: 97*4904Swnj soflush(so); 98*4904Swnj break; 99*4904Swnj 100*4904Swnj case PRU_SHUTDOWN: 101*4904Swnj so->so_state |= SS_CANTSENDMORE; 102*4904Swnj if (so2) { 103*4904Swnj so2->so_state |= SS_CANTRCVMORE; 104*4904Swnj sorwakeup(so2); 105*4904Swnj } 106*4904Swnj break; 107*4904Swnj 108*4904Swnj case PRU_RCVD: 109*4904Swnj if (so->so_rcv.sb_cc == 0 && so2 && so2->so_snd.sb_cc) { 110*4904Swnj so->so_rcv.sb_cc = so2->so_snd.sb_cc; 111*4904Swnj so->so_rcv.sb_mbcnt = so2->so_snd.sb_mbcnt; 112*4904Swnj so->so_rcv.sb_mb = so2->so_rcv.sb_mb; 113*4904Swnj so2->so_snd.sb_cc = 0; 114*4904Swnj so2->so_snd.sb_mbcnt = 0; 115*4904Swnj so2->so_snd.sb_mb = 0; 116*4904Swnj sorwakeup(so); 117*4904Swnj sowwakeup(so2); 118*4904Swnj } 119*4904Swnj break; 120*4904Swnj 121*4904Swnj case PRU_SEND: 122*4904Swnj sbappend(&so->so_snd, m); 123*4904Swnj sorwakeup(so2); 124*4904Swnj break; 125*4904Swnj 126*4904Swnj case PRU_ABORT: 127*4904Swnj return (EOPNOTSUPP); 128*4904Swnj 129*4904Swnj case PRU_CONTROL: 130*4904Swnj return (EOPNOTSUPP); 131*4904Swnj 132*4904Swnj default: 133*4904Swnj panic("pi_usrreq"); 134*4904Swnj } 135*4904Swnj return (0); 136*4904Swnj } 137