xref: /original-bsd/sys/kern/uipc_pipe.c (revision a304ca22)
1 /*	uipc_pipe.c	4.11	82/03/13	*/
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 	if (m_reserve(PIPSIZ*2/MSIZE) == 0) {
35 		u.u_error = ENOBUFS;
36 		return (0);
37 	}
38 	wso->so_proto = rso->so_proto = &pipeproto;
39 	wso->so_pcb = (caddr_t)rso;
40 	rso->so_pcb = (caddr_t)wso;
41 	wso->so_snd.sb_hiwat = PIPSIZ;
42 	wso->so_snd.sb_mbmax = 2*PIPSIZ;
43 	wso->so_state |= SS_ISCONNECTED|SS_CANTRCVMORE;
44 	rso->so_rcv.sb_hiwat = 0;
45 	rso->so_rcv.sb_mbmax = 0;
46 	rso->so_state |= SS_ISCONNECTED|SS_CANTSENDMORE;
47 	return (1);
48 }
49 
50 /*
51  * User requests on pipes and other internally implemented
52  * structures.
53  */
54 /*ARGSUSED*/
55 piusrreq(so, req, m, addr)
56 	struct socket *so;
57 	int req;
58 	struct mbuf *m;
59 	caddr_t addr;
60 {
61 	struct socket *so2 = (struct socket *)so->so_pcb;
62 
63 COUNT(PIUSRREQ);
64 	switch (req) {
65 
66 	case PRU_ATTACH:
67 		break;
68 
69 	case PRU_DETACH:
70 		so->so_pcb = 0;
71 		break;
72 
73 	case PRU_CONNECT:
74 	case PRU_ACCEPT:
75 		return (EOPNOTSUPP);
76 
77 	case PRU_DISCONNECT:
78 		if (so2 == 0)
79 			return (ENOTCONN);
80 		so->so_pcb = 0;
81 		so2->so_pcb = 0;
82 		soisdisconnected(so);
83 		soisdisconnected(so2);
84 		break;
85 
86 	case PRU_SHUTDOWN:
87 		socantsendmore(so);
88 		if (so2)
89 			socantrcvmore(so2);
90 		break;
91 
92 	case PRU_RCVD:
93 		if (so2 == 0)
94 			break;
95 #define	rcv (&so->so_rcv)
96 #define snd (&so2->so_snd)
97 		/*
98 		 * Transfer resources back to send port
99 		 * and wakeup any waiting to write.
100 		 */
101 		snd->sb_mbmax += rcv->sb_mbmax - rcv->sb_mbcnt;
102 		rcv->sb_mbmax = rcv->sb_mbcnt;
103 		snd->sb_hiwat += rcv->sb_hiwat - rcv->sb_cc;
104 		rcv->sb_hiwat = rcv->sb_cc;
105 		sbwakeup(snd);
106 #undef snd
107 #undef rcv
108 		break;
109 
110 	case PRU_SEND:
111 #define	rcv (&so2->so_rcv)
112 #define	snd (&so->so_snd)
113 		if (so2 == 0)
114 			panic("pipe send");
115 		/*
116 		 * Send to paired receive port, and then
117 		 * give it enough resources to hold what it already has.
118 		 * Wake up readers.
119 		 */
120 		sbappend(rcv, m);
121 		snd->sb_mbmax -= rcv->sb_mbcnt - rcv->sb_mbmax;
122 		rcv->sb_mbmax = rcv->sb_mbcnt;
123 		snd->sb_hiwat -= rcv->sb_cc - rcv->sb_hiwat;
124 		rcv->sb_hiwat = rcv->sb_cc;
125 		sbwakeup(rcv);
126 #undef snd
127 #undef rcv
128 		break;
129 
130 	case PRU_ABORT:
131 		return (EOPNOTSUPP);
132 
133 	case PRU_CONTROL:
134 		return (EOPNOTSUPP);
135 
136 	default:
137 		panic("piusrreq");
138 	}
139 	return (0);
140 }
141 
142 #ifdef notdef
143 psndrcv(snd, rcv)
144 	struct sockbuf *snd, *rcv;
145 {
146 
147 	printf("snd: (cc,hiwat,mbcnt,mbmax) (%d,%d,%d,%d) ",
148 	    snd->sb_cc, snd->sb_hiwat, snd->sb_mbcnt, snd->sb_mbmax);
149 	printf("m %x, m->m_len %d\n", snd->sb_mb, snd->sb_mb ? snd->sb_mb->m_len : 0);
150 	printf("rcv: (cc,hiwat,mbcnt,mbmax) (%d,%d,%d,%d) ",
151 	    rcv->sb_cc, rcv->sb_hiwat, rcv->sb_mbcnt, rcv->sb_mbmax);
152 	printf("m %x, m->m_len %d\n", rcv->sb_mb, rcv->sb_mb ? rcv->sb_mb->m_len : 0);
153 }
154 #endif
155