1 /* uipc_pipe.c 4.16 82/10/09 */ 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 11 int piusrreq(); 12 #define PIPSIZ 4096 13 14 /* 15 * Code for pipes and other loopback protocols (single machine, that is.) 16 */ 17 struct protosw pipeproto = { 18 SOCK_STREAM, PF_UNIX, 0, PR_CONNREQUIRED|PR_WANTRCVD, 19 0, 0, 0, 0, 20 piusrreq, 21 0, 0, 0, 0 22 }; 23 24 /* 25 * Connect a pipe from wso to rso. The protocol control block 26 * for a pipe is used to store a pointer to the matching socket. 27 */ 28 piconnect(wso, rso) 29 struct socket *wso, *rso; 30 { 31 32 /* when we reserve memory this routine may fail */ 33 wso->so_proto = rso->so_proto = &pipeproto; 34 wso->so_pcb = (caddr_t)rso; 35 rso->so_pcb = (caddr_t)wso; 36 wso->so_snd.sb_hiwat = PIPSIZ; 37 wso->so_snd.sb_mbmax = 2*PIPSIZ; 38 wso->so_state |= SS_ISCONNECTED|SS_CANTRCVMORE; 39 rso->so_rcv.sb_hiwat = 0; 40 rso->so_rcv.sb_mbmax = 0; 41 rso->so_state |= SS_ISCONNECTED|SS_CANTSENDMORE; 42 return (1); 43 } 44 45 /* 46 * User requests on pipes and other internally implemented 47 * structures. 48 */ 49 /*ARGSUSED*/ 50 piusrreq(so, req, m, addr) 51 struct socket *so; 52 int req; 53 struct mbuf *m; 54 caddr_t addr; 55 { 56 struct socket *so2 = (struct socket *)so->so_pcb; 57 58 switch (req) { 59 60 case PRU_ATTACH: 61 break; 62 63 case PRU_DETACH: 64 so->so_pcb = 0; 65 break; 66 67 case PRU_CONNECT: 68 case PRU_ACCEPT: 69 return (EOPNOTSUPP); 70 71 case PRU_DISCONNECT: 72 if (so2 == 0) 73 return (ENOTCONN); 74 so->so_pcb = 0; 75 so2->so_pcb = 0; 76 soisdisconnected(so); 77 soisdisconnected(so2); 78 break; 79 80 case PRU_SHUTDOWN: 81 socantsendmore(so); 82 if (so2) 83 socantrcvmore(so2); 84 break; 85 86 case PRU_RCVD: 87 if (so2 == 0) 88 break; 89 #define rcv (&so->so_rcv) 90 #define snd (&so2->so_snd) 91 /* 92 * Transfer resources back to send port 93 * and wakeup any waiting to write. 94 */ 95 snd->sb_mbmax += rcv->sb_mbmax - rcv->sb_mbcnt; 96 rcv->sb_mbmax = rcv->sb_mbcnt; 97 snd->sb_hiwat += rcv->sb_hiwat - rcv->sb_cc; 98 rcv->sb_hiwat = rcv->sb_cc; 99 sbwakeup(snd); 100 #undef snd 101 #undef rcv 102 break; 103 104 case PRU_SEND: 105 #define rcv (&so2->so_rcv) 106 #define snd (&so->so_snd) 107 if (so2 == 0) 108 panic("pipe send"); 109 /* 110 * Send to paired receive port, and then 111 * give it enough resources to hold what it already has. 112 * Wake up readers. 113 */ 114 sbappend(rcv, m); 115 snd->sb_mbmax -= rcv->sb_mbcnt - rcv->sb_mbmax; 116 rcv->sb_mbmax = rcv->sb_mbcnt; 117 snd->sb_hiwat -= rcv->sb_cc - rcv->sb_hiwat; 118 rcv->sb_hiwat = rcv->sb_cc; 119 sbwakeup(rcv); 120 #undef snd 121 #undef rcv 122 break; 123 124 case PRU_ABORT: 125 case PRU_CONTROL: 126 case PRU_SENDOOB: 127 case PRU_RCVOOB: 128 return (EOPNOTSUPP); 129 130 default: 131 panic("piusrreq"); 132 } 133 return (0); 134 } 135