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