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