1*5091Swnj /* uipc_pipe.c 4.9 81/11/26 */ 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" 10*5091Swnj #include "../net/in_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; 815021Sroot 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) 974981Swnj /* 984981Swnj * Transfer resources back to send port 994981Swnj * and wakeup any waiting to write. 1004981Swnj */ 1014981Swnj snd->sb_mbmax += rcv->sb_mbmax - rcv->sb_mbcnt; 1024981Swnj rcv->sb_mbmax = rcv->sb_mbcnt; 1034981Swnj snd->sb_hiwat += rcv->sb_hiwat - rcv->sb_cc; 1044981Swnj rcv->sb_hiwat = rcv->sb_cc; 1054981Swnj sbwakeup(snd); 1064981Swnj #undef snd 1074981Swnj #undef rcv 1084904Swnj break; 1094904Swnj 1104904Swnj case PRU_SEND: 1114981Swnj #define rcv (&so2->so_rcv) 1124981Swnj #define snd (&so->so_snd) 1135021Sroot if (so2 == 0) 1145021Sroot panic("pipe send"); 1154981Swnj /* 1164981Swnj * Send to paired receive port, and then 1174981Swnj * give it enough resources to hold what it already has. 1184981Swnj * Wake up readers. 1194981Swnj */ 1204981Swnj sbappend(rcv, m); 1214981Swnj snd->sb_mbmax -= rcv->sb_mbcnt - rcv->sb_mbmax; 1224981Swnj rcv->sb_mbmax = rcv->sb_mbcnt; 1234981Swnj snd->sb_hiwat -= rcv->sb_cc - rcv->sb_hiwat; 1244981Swnj rcv->sb_hiwat = rcv->sb_cc; 1254981Swnj sbwakeup(rcv); 1264981Swnj #undef snd 1274981Swnj #undef rcv 1284904Swnj break; 1294904Swnj 1304904Swnj case PRU_ABORT: 1314904Swnj return (EOPNOTSUPP); 1324904Swnj 1334904Swnj case PRU_CONTROL: 1344904Swnj return (EOPNOTSUPP); 1354904Swnj 1364904Swnj default: 1374927Swnj panic("piusrreq"); 1384904Swnj } 1394904Swnj return (0); 1404904Swnj } 1415010Swnj 1425010Swnj psndrcv(snd, rcv) 1435010Swnj struct sockbuf *snd, *rcv; 1445010Swnj { 1455010Swnj 1465010Swnj printf("snd: (cc,hiwat,mbcnt,mbmax) (%d,%d,%d,%d) ", 1475010Swnj snd->sb_cc, snd->sb_hiwat, snd->sb_mbcnt, snd->sb_mbmax); 1485010Swnj printf("m %x, m->m_len %d\n", snd->sb_mb, snd->sb_mb ? snd->sb_mb->m_len : 0); 1495010Swnj printf("rcv: (cc,hiwat,mbcnt,mbmax) (%d,%d,%d,%d) ", 1505010Swnj rcv->sb_cc, rcv->sb_hiwat, rcv->sb_mbcnt, rcv->sb_mbmax); 1515010Swnj printf("m %x, m->m_len %d\n", rcv->sb_mb, rcv->sb_mb ? rcv->sb_mb->m_len : 0); 1525010Swnj } 153