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