1 /* uipc_pipe.c 4.6 81/11/21 */ 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|PR_WANTRCVD, 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 */ 29 piconnect(wso, rso) 30 struct socket *wso, *rso; 31 { 32 33 COUNT(PICONNECT); 34 if (m_reserve(PIPSIZ/MSIZE) == 0) { 35 u.u_error = ENOBUFS; 36 return (0); 37 } 38 wso->so_proto = rso->so_proto = &pipeproto; 39 wso->so_pcb = (caddr_t)rso; 40 rso->so_pcb = (caddr_t)wso; 41 wso->so_snd.sb_hiwat = PIPSIZ; 42 wso->so_snd.sb_mbmax = 2*PIPSIZ; 43 wso->so_state |= SS_ISCONNECTED|SS_CANTRCVMORE; 44 rso->so_rcv.sb_hiwat = 0; 45 rso->so_rcv.sb_mbmax = 0; 46 rso->so_state |= SS_ISCONNECTED|SS_CANTSENDMORE; 47 return (1); 48 } 49 50 /* 51 * User requests on pipes and other internally implemented 52 * structures. 53 */ 54 /*ARGSUSED*/ 55 piusrreq(so, req, m, addr) 56 struct socket *so; 57 int req; 58 struct mbuf *m; 59 caddr_t addr; 60 { 61 struct socket *so2 = (struct socket *)so->so_pcb; 62 63 COUNT(PIUSRREQ); 64 switch (req) { 65 66 case PRU_ATTACH: 67 break; 68 69 case PRU_DETACH: 70 so->so_pcb = 0; 71 break; 72 73 case PRU_CONNECT: 74 case PRU_ACCEPT: 75 return (EOPNOTSUPP); 76 77 case PRU_DISCONNECT: 78 if (so2 == 0) 79 return (ENOTCONN); 80 so->so_pcb = 0; 81 soisdisconnected(so); 82 soisdisconnected(so2); 83 break; 84 85 case PRU_SHUTDOWN: 86 socantsendmore(so); 87 if (so2) 88 socantrcvmore(so2); 89 break; 90 91 case PRU_RCVD: 92 if (so2 == 0) 93 break; 94 #define rcv (&so->so_rcv) 95 #define snd (&so2->so_snd) 96 /* 97 printf("pru_rcvd in: "); 98 psndrcv(snd, rcv); 99 */ 100 /* 101 * Transfer resources back to send port 102 * and wakeup any waiting to write. 103 */ 104 snd->sb_mbmax += rcv->sb_mbmax - rcv->sb_mbcnt; 105 rcv->sb_mbmax = rcv->sb_mbcnt; 106 snd->sb_hiwat += rcv->sb_hiwat - rcv->sb_cc; 107 rcv->sb_hiwat = rcv->sb_cc; 108 /* 109 printf("pru_rcvd out: "); 110 psndrcv(snd, rcv); 111 */ 112 sbwakeup(snd); 113 #undef snd 114 #undef rcv 115 break; 116 117 case PRU_SEND: 118 #define rcv (&so2->so_rcv) 119 #define snd (&so->so_snd) 120 /* 121 * Send to paired receive port, and then 122 * give it enough resources to hold what it already has. 123 * Wake up readers. 124 */ 125 /* 126 printf("pru_send in: "); 127 psndrcv(snd, rcv); 128 */ 129 sbappend(rcv, m); 130 snd->sb_mbmax -= rcv->sb_mbcnt - rcv->sb_mbmax; 131 rcv->sb_mbmax = rcv->sb_mbcnt; 132 snd->sb_hiwat -= rcv->sb_cc - rcv->sb_hiwat; 133 rcv->sb_hiwat = rcv->sb_cc; 134 sbwakeup(rcv); 135 /* 136 printf("pru_send out: "); 137 psndrcv(snd, rcv); 138 */ 139 #undef snd 140 #undef rcv 141 break; 142 143 case PRU_ABORT: 144 return (EOPNOTSUPP); 145 146 case PRU_CONTROL: 147 return (EOPNOTSUPP); 148 149 default: 150 panic("piusrreq"); 151 } 152 return (0); 153 } 154 155 psndrcv(snd, rcv) 156 struct sockbuf *snd, *rcv; 157 { 158 159 printf("snd: (cc,hiwat,mbcnt,mbmax) (%d,%d,%d,%d) ", 160 snd->sb_cc, snd->sb_hiwat, snd->sb_mbcnt, snd->sb_mbmax); 161 printf("m %x, m->m_len %d\n", snd->sb_mb, snd->sb_mb ? snd->sb_mb->m_len : 0); 162 printf("rcv: (cc,hiwat,mbcnt,mbmax) (%d,%d,%d,%d) ", 163 rcv->sb_cc, rcv->sb_hiwat, rcv->sb_mbcnt, rcv->sb_mbmax); 164 printf("m %x, m->m_len %d\n", rcv->sb_mb, rcv->sb_mb ? rcv->sb_mb->m_len : 0); 165 } 166