1*5021Sroot /* uipc_pipe.c 4.8 81/11/22 */ 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 = { 195010Swnj 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); 345017Swnj if (m_reserve(PIPSIZ*2/MSIZE) == 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: 675010Swnj break; 685010Swnj 694904Swnj case PRU_DETACH: 705010Swnj 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; 81*5021Sroot so2->so_pcb = 0; 824916Swnj soisdisconnected(so); 835010Swnj soisdisconnected(so2); 844904Swnj break; 854904Swnj 864904Swnj case PRU_SHUTDOWN: 874927Swnj socantsendmore(so); 884927Swnj if (so2) 894927Swnj socantrcvmore(so2); 904904Swnj break; 914904Swnj 924904Swnj case PRU_RCVD: 934981Swnj if (so2 == 0) 944981Swnj break; 954981Swnj #define rcv (&so->so_rcv) 964981Swnj #define snd (&so2->so_snd) 975010Swnj /* 985010Swnj printf("pru_rcvd in: "); 995010Swnj psndrcv(snd, rcv); 1005010Swnj */ 1014981Swnj /* 1024981Swnj * Transfer resources back to send port 1034981Swnj * and wakeup any waiting to write. 1044981Swnj */ 1054981Swnj snd->sb_mbmax += rcv->sb_mbmax - rcv->sb_mbcnt; 1064981Swnj rcv->sb_mbmax = rcv->sb_mbcnt; 1074981Swnj snd->sb_hiwat += rcv->sb_hiwat - rcv->sb_cc; 1084981Swnj rcv->sb_hiwat = rcv->sb_cc; 1095010Swnj /* 1105010Swnj printf("pru_rcvd out: "); 1115010Swnj psndrcv(snd, rcv); 1125010Swnj */ 1134981Swnj sbwakeup(snd); 1144981Swnj #undef snd 1154981Swnj #undef rcv 1164904Swnj break; 1174904Swnj 1184904Swnj case PRU_SEND: 1194981Swnj #define rcv (&so2->so_rcv) 1204981Swnj #define snd (&so->so_snd) 121*5021Sroot if (so2 == 0) 122*5021Sroot panic("pipe send"); 1234981Swnj /* 1244981Swnj * Send to paired receive port, and then 1254981Swnj * give it enough resources to hold what it already has. 1264981Swnj * Wake up readers. 1274981Swnj */ 1285010Swnj /* 1295010Swnj printf("pru_send in: "); 1305010Swnj psndrcv(snd, rcv); 1315010Swnj */ 1324981Swnj sbappend(rcv, m); 1334981Swnj snd->sb_mbmax -= rcv->sb_mbcnt - rcv->sb_mbmax; 1344981Swnj rcv->sb_mbmax = rcv->sb_mbcnt; 1354981Swnj snd->sb_hiwat -= rcv->sb_cc - rcv->sb_hiwat; 1364981Swnj rcv->sb_hiwat = rcv->sb_cc; 1374981Swnj sbwakeup(rcv); 1385010Swnj /* 1395010Swnj printf("pru_send out: "); 1405010Swnj psndrcv(snd, rcv); 1415010Swnj */ 1424981Swnj #undef snd 1434981Swnj #undef rcv 1444904Swnj break; 1454904Swnj 1464904Swnj case PRU_ABORT: 1474904Swnj return (EOPNOTSUPP); 1484904Swnj 1494904Swnj case PRU_CONTROL: 1504904Swnj return (EOPNOTSUPP); 1514904Swnj 1524904Swnj default: 1534927Swnj panic("piusrreq"); 1544904Swnj } 1554904Swnj return (0); 1564904Swnj } 1575010Swnj 1585010Swnj psndrcv(snd, rcv) 1595010Swnj struct sockbuf *snd, *rcv; 1605010Swnj { 1615010Swnj 1625010Swnj printf("snd: (cc,hiwat,mbcnt,mbmax) (%d,%d,%d,%d) ", 1635010Swnj snd->sb_cc, snd->sb_hiwat, snd->sb_mbcnt, snd->sb_mbmax); 1645010Swnj printf("m %x, m->m_len %d\n", snd->sb_mb, snd->sb_mb ? snd->sb_mb->m_len : 0); 1655010Swnj printf("rcv: (cc,hiwat,mbcnt,mbmax) (%d,%d,%d,%d) ", 1665010Swnj rcv->sb_cc, rcv->sb_hiwat, rcv->sb_mbcnt, rcv->sb_mbmax); 1675010Swnj printf("m %x, m->m_len %d\n", rcv->sb_mb, rcv->sb_mb ? rcv->sb_mb->m_len : 0); 1685010Swnj } 169