1*4927Swnj /* uipc_pipe.c 4.3 81/11/18 */ 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*4927Swnj #include "../net/inet_systm.h" /* XXX */ 114904Swnj 12*4927Swnj 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, 21*4927Swnj 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 */ 31*4927Swnj piconnect(wso, rso) 324904Swnj struct socket *wso, *rso; 334904Swnj { 344904Swnj 35*4927Swnj 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; 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 /* 534904Swnj * User requests on pipes and other internally implemented 544904Swnj * structures. 554904Swnj */ 564916Swnj /*ARGSUSED*/ 57*4927Swnj 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 65*4927Swnj COUNT(PIUSRREQ); 664904Swnj switch (req) { 674904Swnj 684904Swnj case PRU_ATTACH: 694904Swnj case PRU_DETACH: 704904Swnj break; 714904Swnj 724904Swnj case PRU_CONNECT: 73*4927Swnj 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: 84*4927Swnj socantsendmore(so); 85*4927Swnj if (so2) 86*4927Swnj socantrcvmore(so2); 874904Swnj break; 884904Swnj 894904Swnj case PRU_RCVD: 904904Swnj if (so->so_rcv.sb_cc == 0 && so2 && so2->so_snd.sb_cc) { 914904Swnj so->so_rcv.sb_cc = so2->so_snd.sb_cc; 924904Swnj so->so_rcv.sb_mbcnt = so2->so_snd.sb_mbcnt; 934904Swnj so->so_rcv.sb_mb = so2->so_rcv.sb_mb; 944904Swnj so2->so_snd.sb_cc = 0; 954904Swnj so2->so_snd.sb_mbcnt = 0; 964904Swnj so2->so_snd.sb_mb = 0; 974904Swnj sorwakeup(so); 984904Swnj sowwakeup(so2); 994904Swnj } 1004904Swnj break; 1014904Swnj 1024904Swnj case PRU_SEND: 1034904Swnj sbappend(&so->so_snd, m); 1044904Swnj sorwakeup(so2); 1054904Swnj break; 1064904Swnj 1074904Swnj case PRU_ABORT: 1084904Swnj return (EOPNOTSUPP); 1094904Swnj 1104904Swnj case PRU_CONTROL: 1114904Swnj return (EOPNOTSUPP); 1124904Swnj 1134904Swnj default: 114*4927Swnj panic("piusrreq"); 1154904Swnj } 1164904Swnj return (0); 1174904Swnj } 118