1*4981Swnj /* uipc_pipe.c 4.4 81/11/21 */ 24904Swnj 34904Swnj #include "../h/param.h" 44904Swnj #include "../h/dir.h" 54904Swnj #include "../h/user.h" 64904Swnj #include "../h/mbuf.h" 74904Swnj #include "../h/protosw.h" 84904Swnj #include "../h/socket.h" 94904Swnj #include "../h/socketvar.h" 104927Swnj #include "../net/inet_systm.h" /* XXX */ 114904Swnj 124927Swnj int piusrreq(); 134904Swnj #define PIPSIZ 4096 144904Swnj 154904Swnj /* 164904Swnj * Code for pipes and other loopback protocols (single machine, that is.) 174904Swnj */ 184904Swnj struct protosw pipeproto = { 194904Swnj SOCK_STREAM, PF_LOCAL, 0, PR_CONNREQUIRED, 204904Swnj 0, 0, 0, 0, 214927Swnj piusrreq, 0, 0, 224904Swnj 0, 0, 0, 0 234904Swnj }; 244904Swnj 254904Swnj /* 264904Swnj * Connect a pipe from wso to rso. The protocol control block 274904Swnj * for a pipe is used to store a pointer to the matching socket. 284904Swnj * Each half of the pipe gets half of the buffer space (half send 294904Swnj * buffers, half receive buffers). 304904Swnj */ 314927Swnj piconnect(wso, rso) 324904Swnj struct socket *wso, *rso; 334904Swnj { 344904Swnj 354927Swnj COUNT(PICONNECT); 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; 43*4981Swnj wso->so_snd.sb_hiwat = PIPSIZ; 44*4981Swnj wso->so_snd.sb_mbmax = 2*PIPSIZ; 454904Swnj wso->so_state |= SS_ISCONNECTED|SS_CANTRCVMORE; 46*4981Swnj rso->so_rcv.sb_hiwat = 0; 47*4981Swnj rso->so_rcv.sb_mbmax = 0; 484904Swnj rso->so_state |= SS_ISCONNECTED|SS_CANTSENDMORE; 494904Swnj return (1); 504904Swnj } 514904Swnj 524904Swnj /* 534904Swnj * User requests on pipes and other internally implemented 544904Swnj * structures. 554904Swnj */ 564916Swnj /*ARGSUSED*/ 574927Swnj piusrreq(so, req, m, addr) 584904Swnj struct socket *so; 594904Swnj int req; 604904Swnj struct mbuf *m; 614904Swnj caddr_t addr; 624904Swnj { 634904Swnj struct socket *so2 = (struct socket *)so->so_pcb; 644904Swnj 654927Swnj COUNT(PIUSRREQ); 664904Swnj switch (req) { 674904Swnj 684904Swnj case PRU_ATTACH: 694904Swnj case PRU_DETACH: 704904Swnj break; 714904Swnj 724904Swnj case PRU_CONNECT: 734927Swnj case PRU_ACCEPT: 744904Swnj return (EOPNOTSUPP); 754904Swnj 764904Swnj case PRU_DISCONNECT: 774904Swnj if (so2 == 0) 784904Swnj return (ENOTCONN); 794904Swnj so->so_pcb = 0; 804916Swnj soisdisconnected(so); 814904Swnj break; 824904Swnj 834904Swnj case PRU_SHUTDOWN: 844927Swnj socantsendmore(so); 854927Swnj if (so2) 864927Swnj socantrcvmore(so2); 874904Swnj break; 884904Swnj 894904Swnj case PRU_RCVD: 90*4981Swnj if (so2 == 0) 91*4981Swnj break; 92*4981Swnj #define rcv (&so->so_rcv) 93*4981Swnj #define snd (&so2->so_snd) 94*4981Swnj /* 95*4981Swnj * Transfer resources back to send port 96*4981Swnj * and wakeup any waiting to write. 97*4981Swnj */ 98*4981Swnj snd->sb_mbmax += rcv->sb_mbmax - rcv->sb_mbcnt; 99*4981Swnj rcv->sb_mbmax = rcv->sb_mbcnt; 100*4981Swnj snd->sb_hiwat += rcv->sb_hiwat - rcv->sb_cc; 101*4981Swnj rcv->sb_hiwat = rcv->sb_cc; 102*4981Swnj sbwakeup(snd); 103*4981Swnj #undef snd 104*4981Swnj #undef rcv 1054904Swnj break; 1064904Swnj 1074904Swnj case PRU_SEND: 108*4981Swnj #define rcv (&so2->so_rcv) 109*4981Swnj #define snd (&so->so_snd) 110*4981Swnj /* 111*4981Swnj * Send to paired receive port, and then 112*4981Swnj * give it enough resources to hold what it already has. 113*4981Swnj * Wake up readers. 114*4981Swnj */ 115*4981Swnj sbappend(rcv, m); 116*4981Swnj snd->sb_mbmax -= rcv->sb_mbcnt - rcv->sb_mbmax; 117*4981Swnj rcv->sb_mbmax = rcv->sb_mbcnt; 118*4981Swnj snd->sb_hiwat -= rcv->sb_cc - rcv->sb_hiwat; 119*4981Swnj rcv->sb_hiwat = rcv->sb_cc; 120*4981Swnj sbwakeup(rcv); 121*4981Swnj #undef snd 122*4981Swnj #undef rcv 1234904Swnj break; 1244904Swnj 1254904Swnj case PRU_ABORT: 1264904Swnj return (EOPNOTSUPP); 1274904Swnj 1284904Swnj case PRU_CONTROL: 1294904Swnj return (EOPNOTSUPP); 1304904Swnj 1314904Swnj default: 1324927Swnj panic("piusrreq"); 1334904Swnj } 1344904Swnj return (0); 1354904Swnj } 136