1 /* uipc_pipe.c 4.3 81/11/18 */ 2 3 #include "../h/param.h" 4 #include "../h/dir.h" 5 #include "../h/user.h" 6 #include "../h/mbuf.h" 7 #include "../h/protosw.h" 8 #include "../h/socket.h" 9 #include "../h/socketvar.h" 10 #include "../net/inet_systm.h" /* XXX */ 11 12 int piusrreq(); 13 #define PIPSIZ 4096 14 15 /* 16 * Code for pipes and other loopback protocols (single machine, that is.) 17 */ 18 struct protosw pipeproto = { 19 SOCK_STREAM, PF_LOCAL, 0, PR_CONNREQUIRED, 20 0, 0, 0, 0, 21 piusrreq, 0, 0, 22 0, 0, 0, 0 23 }; 24 25 /* 26 * Connect a pipe from wso to rso. The protocol control block 27 * for a pipe is used to store a pointer to the matching socket. 28 * Each half of the pipe gets half of the buffer space (half send 29 * buffers, half receive buffers). 30 */ 31 piconnect(wso, rso) 32 struct socket *wso, *rso; 33 { 34 35 COUNT(PICONNECT); 36 if (m_reserve(PIPSIZ) == 0) { 37 u.u_error = ENOBUFS; 38 return (0); 39 } 40 wso->so_proto = rso->so_proto = &pipeproto; 41 wso->so_pcb = (caddr_t)rso; 42 rso->so_pcb = (caddr_t)wso; 43 wso->so_snd.sb_hiwat = PIPSIZ/2; 44 wso->so_snd.sb_mbcnt = PIPSIZ; 45 wso->so_state |= SS_ISCONNECTED|SS_CANTRCVMORE; 46 rso->so_rcv.sb_hiwat = PIPSIZ/2; 47 rso->so_rcv.sb_mbcnt = PIPSIZ; 48 rso->so_state |= SS_ISCONNECTED|SS_CANTSENDMORE; 49 return (1); 50 } 51 52 /* 53 * User requests on pipes and other internally implemented 54 * structures. 55 */ 56 /*ARGSUSED*/ 57 piusrreq(so, req, m, addr) 58 struct socket *so; 59 int req; 60 struct mbuf *m; 61 caddr_t addr; 62 { 63 struct socket *so2 = (struct socket *)so->so_pcb; 64 65 COUNT(PIUSRREQ); 66 switch (req) { 67 68 case PRU_ATTACH: 69 case PRU_DETACH: 70 break; 71 72 case PRU_CONNECT: 73 case PRU_ACCEPT: 74 return (EOPNOTSUPP); 75 76 case PRU_DISCONNECT: 77 if (so2 == 0) 78 return (ENOTCONN); 79 so->so_pcb = 0; 80 soisdisconnected(so); 81 break; 82 83 case PRU_SHUTDOWN: 84 socantsendmore(so); 85 if (so2) 86 socantrcvmore(so2); 87 break; 88 89 case PRU_RCVD: 90 if (so->so_rcv.sb_cc == 0 && so2 && so2->so_snd.sb_cc) { 91 so->so_rcv.sb_cc = so2->so_snd.sb_cc; 92 so->so_rcv.sb_mbcnt = so2->so_snd.sb_mbcnt; 93 so->so_rcv.sb_mb = so2->so_rcv.sb_mb; 94 so2->so_snd.sb_cc = 0; 95 so2->so_snd.sb_mbcnt = 0; 96 so2->so_snd.sb_mb = 0; 97 sorwakeup(so); 98 sowwakeup(so2); 99 } 100 break; 101 102 case PRU_SEND: 103 sbappend(&so->so_snd, m); 104 sorwakeup(so2); 105 break; 106 107 case PRU_ABORT: 108 return (EOPNOTSUPP); 109 110 case PRU_CONTROL: 111 return (EOPNOTSUPP); 112 113 default: 114 panic("piusrreq"); 115 } 116 return (0); 117 } 118