xref: /csrg-svn/sys/kern/uipc_pipe.c (revision 4927)
1 /*	uipc_pipe.c	4.3	81/11/18	*/
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,
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  * Each half of the pipe gets half of the buffer space (half send
29  * buffers, half receive buffers).
30  */
31 piconnect(wso, rso)
32 	struct socket *wso, *rso;
33 {
34 
35 COUNT(PICONNECT);
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 /*
53  * User requests on pipes and other internally implemented
54  * structures.
55  */
56 /*ARGSUSED*/
57 piusrreq(so, req, m, addr)
58 	struct socket *so;
59 	int req;
60 	struct mbuf *m;
61 	caddr_t addr;
62 {
63 	struct socket *so2 = (struct socket *)so->so_pcb;
64 
65 COUNT(PIUSRREQ);
66 	switch (req) {
67 
68 	case PRU_ATTACH:
69 	case PRU_DETACH:
70 		break;
71 
72 	case PRU_CONNECT:
73 	case PRU_ACCEPT:
74 		return (EOPNOTSUPP);
75 
76 	case PRU_DISCONNECT:
77 		if (so2 == 0)
78 			return (ENOTCONN);
79 		so->so_pcb = 0;
80 		soisdisconnected(so);
81 		break;
82 
83 	case PRU_SHUTDOWN:
84 		socantsendmore(so);
85 		if (so2)
86 			socantrcvmore(so2);
87 		break;
88 
89 	case PRU_RCVD:
90 		if (so->so_rcv.sb_cc == 0 && so2 && so2->so_snd.sb_cc) {
91 			so->so_rcv.sb_cc = so2->so_snd.sb_cc;
92 			so->so_rcv.sb_mbcnt = so2->so_snd.sb_mbcnt;
93 			so->so_rcv.sb_mb = so2->so_rcv.sb_mb;
94 			so2->so_snd.sb_cc = 0;
95 			so2->so_snd.sb_mbcnt = 0;
96 			so2->so_snd.sb_mb = 0;
97 			sorwakeup(so);
98 			sowwakeup(so2);
99 		}
100 		break;
101 
102 	case PRU_SEND:
103 		sbappend(&so->so_snd, m);
104 		sorwakeup(so2);
105 		break;
106 
107 	case PRU_ABORT:
108 		return (EOPNOTSUPP);
109 
110 	case PRU_CONTROL:
111 		return (EOPNOTSUPP);
112 
113 	default:
114 		panic("piusrreq");
115 	}
116 	return (0);
117 }
118