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