xref: /csrg-svn/sys/kern/uipc_pipe.c (revision 7180)
1 /*	uipc_pipe.c	4.12	82/06/14	*/
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/in_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_UNIX,	0,		PR_CONNREQUIRED|PR_WANTRCVD,
20 	0,		0,		0,		0,
21 	piusrreq,
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 	/* when we reserve memory this routine may fail */
35 	wso->so_proto = rso->so_proto = &pipeproto;
36 	wso->so_pcb = (caddr_t)rso;
37 	rso->so_pcb = (caddr_t)wso;
38 	wso->so_snd.sb_hiwat = PIPSIZ;
39 	wso->so_snd.sb_mbmax = 2*PIPSIZ;
40 	wso->so_state |= SS_ISCONNECTED|SS_CANTRCVMORE;
41 	rso->so_rcv.sb_hiwat = 0;
42 	rso->so_rcv.sb_mbmax = 0;
43 	rso->so_state |= SS_ISCONNECTED|SS_CANTSENDMORE;
44 	return (1);
45 }
46 
47 /*
48  * User requests on pipes and other internally implemented
49  * structures.
50  */
51 /*ARGSUSED*/
52 piusrreq(so, req, m, addr)
53 	struct socket *so;
54 	int req;
55 	struct mbuf *m;
56 	caddr_t addr;
57 {
58 	struct socket *so2 = (struct socket *)so->so_pcb;
59 
60 COUNT(PIUSRREQ);
61 	switch (req) {
62 
63 	case PRU_ATTACH:
64 		break;
65 
66 	case PRU_DETACH:
67 		so->so_pcb = 0;
68 		break;
69 
70 	case PRU_CONNECT:
71 	case PRU_ACCEPT:
72 		return (EOPNOTSUPP);
73 
74 	case PRU_DISCONNECT:
75 		if (so2 == 0)
76 			return (ENOTCONN);
77 		so->so_pcb = 0;
78 		so2->so_pcb = 0;
79 		soisdisconnected(so);
80 		soisdisconnected(so2);
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 (so2 == 0)
91 			break;
92 #define	rcv (&so->so_rcv)
93 #define snd (&so2->so_snd)
94 		/*
95 		 * Transfer resources back to send port
96 		 * and wakeup any waiting to write.
97 		 */
98 		snd->sb_mbmax += rcv->sb_mbmax - rcv->sb_mbcnt;
99 		rcv->sb_mbmax = rcv->sb_mbcnt;
100 		snd->sb_hiwat += rcv->sb_hiwat - rcv->sb_cc;
101 		rcv->sb_hiwat = rcv->sb_cc;
102 		sbwakeup(snd);
103 #undef snd
104 #undef rcv
105 		break;
106 
107 	case PRU_SEND:
108 #define	rcv (&so2->so_rcv)
109 #define	snd (&so->so_snd)
110 		if (so2 == 0)
111 			panic("pipe send");
112 		/*
113 		 * Send to paired receive port, and then
114 		 * give it enough resources to hold what it already has.
115 		 * Wake up readers.
116 		 */
117 		sbappend(rcv, m);
118 		snd->sb_mbmax -= rcv->sb_mbcnt - rcv->sb_mbmax;
119 		rcv->sb_mbmax = rcv->sb_mbcnt;
120 		snd->sb_hiwat -= rcv->sb_cc - rcv->sb_hiwat;
121 		rcv->sb_hiwat = rcv->sb_cc;
122 		sbwakeup(rcv);
123 #undef snd
124 #undef rcv
125 		break;
126 
127 	case PRU_ABORT:
128 		return (EOPNOTSUPP);
129 
130 	case PRU_CONTROL:
131 		return (EOPNOTSUPP);
132 
133 	default:
134 		panic("piusrreq");
135 	}
136 	return (0);
137 }
138