1 /* uipc_pipe.c 4.11 82/03/13 */ 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/in_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_UNIX, 0, PR_CONNREQUIRED|PR_WANTRCVD, 20 0, 0, 0, 0, 21 piusrreq, 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*2/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 so2->so_pcb = 0; 82 soisdisconnected(so); 83 soisdisconnected(so2); 84 break; 85 86 case PRU_SHUTDOWN: 87 socantsendmore(so); 88 if (so2) 89 socantrcvmore(so2); 90 break; 91 92 case PRU_RCVD: 93 if (so2 == 0) 94 break; 95 #define rcv (&so->so_rcv) 96 #define snd (&so2->so_snd) 97 /* 98 * Transfer resources back to send port 99 * and wakeup any waiting to write. 100 */ 101 snd->sb_mbmax += rcv->sb_mbmax - rcv->sb_mbcnt; 102 rcv->sb_mbmax = rcv->sb_mbcnt; 103 snd->sb_hiwat += rcv->sb_hiwat - rcv->sb_cc; 104 rcv->sb_hiwat = rcv->sb_cc; 105 sbwakeup(snd); 106 #undef snd 107 #undef rcv 108 break; 109 110 case PRU_SEND: 111 #define rcv (&so2->so_rcv) 112 #define snd (&so->so_snd) 113 if (so2 == 0) 114 panic("pipe send"); 115 /* 116 * Send to paired receive port, and then 117 * give it enough resources to hold what it already has. 118 * Wake up readers. 119 */ 120 sbappend(rcv, m); 121 snd->sb_mbmax -= rcv->sb_mbcnt - rcv->sb_mbmax; 122 rcv->sb_mbmax = rcv->sb_mbcnt; 123 snd->sb_hiwat -= rcv->sb_cc - rcv->sb_hiwat; 124 rcv->sb_hiwat = rcv->sb_cc; 125 sbwakeup(rcv); 126 #undef snd 127 #undef rcv 128 break; 129 130 case PRU_ABORT: 131 return (EOPNOTSUPP); 132 133 case PRU_CONTROL: 134 return (EOPNOTSUPP); 135 136 default: 137 panic("piusrreq"); 138 } 139 return (0); 140 } 141 142 #ifdef notdef 143 psndrcv(snd, rcv) 144 struct sockbuf *snd, *rcv; 145 { 146 147 printf("snd: (cc,hiwat,mbcnt,mbmax) (%d,%d,%d,%d) ", 148 snd->sb_cc, snd->sb_hiwat, snd->sb_mbcnt, snd->sb_mbmax); 149 printf("m %x, m->m_len %d\n", snd->sb_mb, snd->sb_mb ? snd->sb_mb->m_len : 0); 150 printf("rcv: (cc,hiwat,mbcnt,mbmax) (%d,%d,%d,%d) ", 151 rcv->sb_cc, rcv->sb_hiwat, rcv->sb_mbcnt, rcv->sb_mbmax); 152 printf("m %x, m->m_len %d\n", rcv->sb_mb, rcv->sb_mb ? rcv->sb_mb->m_len : 0); 153 } 154 #endif 155