1*4916Swnj /* uipc_pipe.c 4.2 81/11/16 */ 24904Swnj 34904Swnj #include "../h/param.h" 44904Swnj #include "../h/dir.h" 54904Swnj #include "../h/user.h" 64904Swnj #include "../h/mbuf.h" 74904Swnj #include "../h/protocol.h" 84904Swnj #include "../h/protosw.h" 94904Swnj #include "../h/socket.h" 104904Swnj #include "../h/socketvar.h" 114904Swnj #include "../h/inaddr.h" 124904Swnj 134904Swnj int pi_usrreq(); 144904Swnj #define PIPSIZ 4096 154904Swnj 164904Swnj /* 174904Swnj * Code for pipes and other loopback protocols (single machine, that is.) 184904Swnj */ 194904Swnj struct protosw pipeproto = { 204904Swnj SOCK_STREAM, PF_LOCAL, 0, PR_CONNREQUIRED, 214904Swnj 0, 0, 0, 0, 224904Swnj pi_usrreq, 0, 0, 234904Swnj 0, 0, 0, 0 244904Swnj }; 254904Swnj 264904Swnj /* 274904Swnj * Connect a pipe from wso to rso. The protocol control block 284904Swnj * for a pipe is used to store a pointer to the matching socket. 294904Swnj * Each half of the pipe gets half of the buffer space (half send 304904Swnj * buffers, half receive buffers). 314904Swnj */ 324904Swnj pi_connect(wso, rso) 334904Swnj struct socket *wso, *rso; 344904Swnj { 354904Swnj 364904Swnj if (m_reserve(PIPSIZ) == 0) { 374904Swnj u.u_error = ENOBUFS; 384904Swnj return (0); 394904Swnj } 404904Swnj wso->so_proto = rso->so_proto = &pipeproto; 414904Swnj wso->so_pcb = (caddr_t)rso; 424904Swnj rso->so_pcb = (caddr_t)wso; 434904Swnj wso->so_snd.sb_hiwat = PIPSIZ/2; 444904Swnj wso->so_snd.sb_mbcnt = PIPSIZ; 454904Swnj wso->so_state |= SS_ISCONNECTED|SS_CANTRCVMORE; 464904Swnj rso->so_rcv.sb_hiwat = PIPSIZ/2; 474904Swnj rso->so_rcv.sb_mbcnt = PIPSIZ; 484904Swnj rso->so_state |= SS_ISCONNECTED|SS_CANTSENDMORE; 494904Swnj return (1); 504904Swnj } 514904Swnj 524904Swnj pi_splice(pso, so) 534904Swnj struct socket *pso, *so; 544904Swnj { 554904Swnj 564904Swnj if (pso->so_proto != &pipeproto) { 574904Swnj struct socket *tso; 584904Swnj tso = pso; pso = so; so = tso; 594904Swnj } 604904Swnj if (pso->so_proto != &pipeproto) 614904Swnj return (EOPNOTSUPP); 624904Swnj /* check types and buffer space */ 634904Swnj /* merge buffers */ 644904Swnj return (0); 654904Swnj } 664904Swnj 674904Swnj /* 684904Swnj * User requests on pipes and other internally implemented 694904Swnj * structures. 704904Swnj */ 71*4916Swnj /*ARGSUSED*/ 724904Swnj pi_usrreq(so, req, m, addr) 734904Swnj struct socket *so; 744904Swnj int req; 754904Swnj struct mbuf *m; 764904Swnj caddr_t addr; 774904Swnj { 784904Swnj struct socket *so2 = (struct socket *)so->so_pcb; 794904Swnj 804904Swnj switch (req) { 814904Swnj 824904Swnj case PRU_ATTACH: 834904Swnj case PRU_DETACH: 844904Swnj break; 854904Swnj 864904Swnj case PRU_CONNECT: 874904Swnj return (EOPNOTSUPP); 884904Swnj 894904Swnj case PRU_DISCONNECT: 904904Swnj if (so2 == 0) 914904Swnj return (ENOTCONN); 924904Swnj so->so_pcb = 0; 93*4916Swnj soisdisconnected(so); 944904Swnj break; 954904Swnj 964904Swnj case PRU_FLUSH: 97*4916Swnj return (EOPNOTSUPP); 984904Swnj 994904Swnj case PRU_SHUTDOWN: 1004904Swnj so->so_state |= SS_CANTSENDMORE; 101*4916Swnj sowwakeup(so); 1024904Swnj if (so2) { 1034904Swnj so2->so_state |= SS_CANTRCVMORE; 1044904Swnj sorwakeup(so2); 1054904Swnj } 1064904Swnj break; 1074904Swnj 1084904Swnj case PRU_RCVD: 1094904Swnj if (so->so_rcv.sb_cc == 0 && so2 && so2->so_snd.sb_cc) { 1104904Swnj so->so_rcv.sb_cc = so2->so_snd.sb_cc; 1114904Swnj so->so_rcv.sb_mbcnt = so2->so_snd.sb_mbcnt; 1124904Swnj so->so_rcv.sb_mb = so2->so_rcv.sb_mb; 1134904Swnj so2->so_snd.sb_cc = 0; 1144904Swnj so2->so_snd.sb_mbcnt = 0; 1154904Swnj so2->so_snd.sb_mb = 0; 1164904Swnj sorwakeup(so); 1174904Swnj sowwakeup(so2); 1184904Swnj } 1194904Swnj break; 1204904Swnj 1214904Swnj case PRU_SEND: 1224904Swnj sbappend(&so->so_snd, m); 1234904Swnj sorwakeup(so2); 1244904Swnj break; 1254904Swnj 1264904Swnj case PRU_ABORT: 1274904Swnj return (EOPNOTSUPP); 1284904Swnj 1294904Swnj case PRU_CONTROL: 1304904Swnj return (EOPNOTSUPP); 1314904Swnj 1324904Swnj default: 1334904Swnj panic("pi_usrreq"); 1344904Swnj } 1354904Swnj return (0); 1364904Swnj } 137