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