xref: /csrg-svn/sys/kern/uipc_pipe.c (revision 5015)
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