1*5010Swnj /* uipc_pipe.c 4.5 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 = { 19*5010Swnj SOCK_STREAM, PF_LOCAL, 0, PR_CONNREQUIRED|PR_WANTRCVD, 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 */ 294927Swnj piconnect(wso, rso) 304904Swnj struct socket *wso, *rso; 314904Swnj { 324904Swnj 334927Swnj COUNT(PICONNECT); 344904Swnj if (m_reserve(PIPSIZ) == 0) { 354904Swnj u.u_error = ENOBUFS; 364904Swnj return (0); 374904Swnj } 384904Swnj wso->so_proto = rso->so_proto = &pipeproto; 394904Swnj wso->so_pcb = (caddr_t)rso; 404904Swnj rso->so_pcb = (caddr_t)wso; 414981Swnj wso->so_snd.sb_hiwat = PIPSIZ; 424981Swnj wso->so_snd.sb_mbmax = 2*PIPSIZ; 434904Swnj wso->so_state |= SS_ISCONNECTED|SS_CANTRCVMORE; 444981Swnj rso->so_rcv.sb_hiwat = 0; 454981Swnj rso->so_rcv.sb_mbmax = 0; 464904Swnj rso->so_state |= SS_ISCONNECTED|SS_CANTSENDMORE; 474904Swnj return (1); 484904Swnj } 494904Swnj 504904Swnj /* 514904Swnj * User requests on pipes and other internally implemented 524904Swnj * structures. 534904Swnj */ 544916Swnj /*ARGSUSED*/ 554927Swnj piusrreq(so, req, m, addr) 564904Swnj struct socket *so; 574904Swnj int req; 584904Swnj struct mbuf *m; 594904Swnj caddr_t addr; 604904Swnj { 614904Swnj struct socket *so2 = (struct socket *)so->so_pcb; 624904Swnj 634927Swnj COUNT(PIUSRREQ); 644904Swnj switch (req) { 654904Swnj 664904Swnj case PRU_ATTACH: 67*5010Swnj break; 68*5010Swnj 694904Swnj case PRU_DETACH: 70*5010Swnj so->so_pcb = 0; 714904Swnj break; 724904Swnj 734904Swnj case PRU_CONNECT: 744927Swnj case PRU_ACCEPT: 754904Swnj return (EOPNOTSUPP); 764904Swnj 774904Swnj case PRU_DISCONNECT: 784904Swnj if (so2 == 0) 794904Swnj return (ENOTCONN); 804904Swnj so->so_pcb = 0; 814916Swnj soisdisconnected(so); 82*5010Swnj soisdisconnected(so2); 834904Swnj break; 844904Swnj 854904Swnj case PRU_SHUTDOWN: 864927Swnj socantsendmore(so); 874927Swnj if (so2) 884927Swnj socantrcvmore(so2); 894904Swnj break; 904904Swnj 914904Swnj case PRU_RCVD: 924981Swnj if (so2 == 0) 934981Swnj break; 944981Swnj #define rcv (&so->so_rcv) 954981Swnj #define snd (&so2->so_snd) 96*5010Swnj /* 97*5010Swnj printf("pru_rcvd in: "); 98*5010Swnj psndrcv(snd, rcv); 99*5010Swnj */ 1004981Swnj /* 1014981Swnj * Transfer resources back to send port 1024981Swnj * and wakeup any waiting to write. 1034981Swnj */ 1044981Swnj snd->sb_mbmax += rcv->sb_mbmax - rcv->sb_mbcnt; 1054981Swnj rcv->sb_mbmax = rcv->sb_mbcnt; 1064981Swnj snd->sb_hiwat += rcv->sb_hiwat - rcv->sb_cc; 1074981Swnj rcv->sb_hiwat = rcv->sb_cc; 108*5010Swnj /* 109*5010Swnj printf("pru_rcvd out: "); 110*5010Swnj psndrcv(snd, rcv); 111*5010Swnj */ 1124981Swnj sbwakeup(snd); 1134981Swnj #undef snd 1144981Swnj #undef rcv 1154904Swnj break; 1164904Swnj 1174904Swnj case PRU_SEND: 1184981Swnj #define rcv (&so2->so_rcv) 1194981Swnj #define snd (&so->so_snd) 1204981Swnj /* 1214981Swnj * Send to paired receive port, and then 1224981Swnj * give it enough resources to hold what it already has. 1234981Swnj * Wake up readers. 1244981Swnj */ 125*5010Swnj /* 126*5010Swnj printf("pru_send in: "); 127*5010Swnj psndrcv(snd, rcv); 128*5010Swnj */ 1294981Swnj sbappend(rcv, m); 1304981Swnj snd->sb_mbmax -= rcv->sb_mbcnt - rcv->sb_mbmax; 1314981Swnj rcv->sb_mbmax = rcv->sb_mbcnt; 1324981Swnj snd->sb_hiwat -= rcv->sb_cc - rcv->sb_hiwat; 1334981Swnj rcv->sb_hiwat = rcv->sb_cc; 1344981Swnj sbwakeup(rcv); 135*5010Swnj /* 136*5010Swnj printf("pru_send out: "); 137*5010Swnj psndrcv(snd, rcv); 138*5010Swnj */ 1394981Swnj #undef snd 1404981Swnj #undef rcv 1414904Swnj break; 1424904Swnj 1434904Swnj case PRU_ABORT: 1444904Swnj return (EOPNOTSUPP); 1454904Swnj 1464904Swnj case PRU_CONTROL: 1474904Swnj return (EOPNOTSUPP); 1484904Swnj 1494904Swnj default: 1504927Swnj panic("piusrreq"); 1514904Swnj } 1524904Swnj return (0); 1534904Swnj } 154*5010Swnj 155*5010Swnj psndrcv(snd, rcv) 156*5010Swnj struct sockbuf *snd, *rcv; 157*5010Swnj { 158*5010Swnj 159*5010Swnj printf("snd: (cc,hiwat,mbcnt,mbmax) (%d,%d,%d,%d) ", 160*5010Swnj snd->sb_cc, snd->sb_hiwat, snd->sb_mbcnt, snd->sb_mbmax); 161*5010Swnj printf("m %x, m->m_len %d\n", snd->sb_mb, snd->sb_mb ? snd->sb_mb->m_len : 0); 162*5010Swnj printf("rcv: (cc,hiwat,mbcnt,mbmax) (%d,%d,%d,%d) ", 163*5010Swnj rcv->sb_cc, rcv->sb_hiwat, rcv->sb_mbcnt, rcv->sb_mbmax); 164*5010Swnj printf("m %x, m->m_len %d\n", rcv->sb_mb, rcv->sb_mb ? rcv->sb_mb->m_len : 0); 165*5010Swnj } 166