xref: /csrg-svn/sys/kern/uipc_pipe.c (revision 4981)
1*4981Swnj /*	uipc_pipe.c	4.4	81/11/21	*/
24904Swnj 
34904Swnj #include "../h/param.h"
44904Swnj #include "../h/dir.h"
54904Swnj #include "../h/user.h"
64904Swnj #include "../h/mbuf.h"
74904Swnj #include "../h/protosw.h"
84904Swnj #include "../h/socket.h"
94904Swnj #include "../h/socketvar.h"
104927Swnj #include "../net/inet_systm.h"		/* XXX */
114904Swnj 
124927Swnj int	piusrreq();
134904Swnj #define	PIPSIZ	4096
144904Swnj 
154904Swnj /*
164904Swnj  * Code for pipes and other loopback protocols (single machine, that is.)
174904Swnj  */
184904Swnj struct	protosw pipeproto = {
194904Swnj 	SOCK_STREAM,	PF_LOCAL,	0,		PR_CONNREQUIRED,
204904Swnj 	0,		0,		0,		0,
214927Swnj 	piusrreq,	0,		0,
224904Swnj 	0,		0,		0,		0
234904Swnj };
244904Swnj 
254904Swnj /*
264904Swnj  * Connect a pipe from wso to rso.  The protocol control block
274904Swnj  * for a pipe is used to store a pointer to the matching socket.
284904Swnj  * Each half of the pipe gets half of the buffer space (half send
294904Swnj  * buffers, half receive buffers).
304904Swnj  */
314927Swnj piconnect(wso, rso)
324904Swnj 	struct socket *wso, *rso;
334904Swnj {
344904Swnj 
354927Swnj COUNT(PICONNECT);
364904Swnj 	if (m_reserve(PIPSIZ) == 0) {
374904Swnj 		u.u_error = ENOBUFS;
384904Swnj 		return (0);
394904Swnj 	}
404904Swnj 	wso->so_proto = rso->so_proto = &pipeproto;
414904Swnj 	wso->so_pcb = (caddr_t)rso;
424904Swnj 	rso->so_pcb = (caddr_t)wso;
43*4981Swnj 	wso->so_snd.sb_hiwat = PIPSIZ;
44*4981Swnj 	wso->so_snd.sb_mbmax = 2*PIPSIZ;
454904Swnj 	wso->so_state |= SS_ISCONNECTED|SS_CANTRCVMORE;
46*4981Swnj 	rso->so_rcv.sb_hiwat = 0;
47*4981Swnj 	rso->so_rcv.sb_mbmax = 0;
484904Swnj 	rso->so_state |= SS_ISCONNECTED|SS_CANTSENDMORE;
494904Swnj 	return (1);
504904Swnj }
514904Swnj 
524904Swnj /*
534904Swnj  * User requests on pipes and other internally implemented
544904Swnj  * structures.
554904Swnj  */
564916Swnj /*ARGSUSED*/
574927Swnj piusrreq(so, req, m, addr)
584904Swnj 	struct socket *so;
594904Swnj 	int req;
604904Swnj 	struct mbuf *m;
614904Swnj 	caddr_t addr;
624904Swnj {
634904Swnj 	struct socket *so2 = (struct socket *)so->so_pcb;
644904Swnj 
654927Swnj COUNT(PIUSRREQ);
664904Swnj 	switch (req) {
674904Swnj 
684904Swnj 	case PRU_ATTACH:
694904Swnj 	case PRU_DETACH:
704904Swnj 		break;
714904Swnj 
724904Swnj 	case PRU_CONNECT:
734927Swnj 	case PRU_ACCEPT:
744904Swnj 		return (EOPNOTSUPP);
754904Swnj 
764904Swnj 	case PRU_DISCONNECT:
774904Swnj 		if (so2 == 0)
784904Swnj 			return (ENOTCONN);
794904Swnj 		so->so_pcb = 0;
804916Swnj 		soisdisconnected(so);
814904Swnj 		break;
824904Swnj 
834904Swnj 	case PRU_SHUTDOWN:
844927Swnj 		socantsendmore(so);
854927Swnj 		if (so2)
864927Swnj 			socantrcvmore(so2);
874904Swnj 		break;
884904Swnj 
894904Swnj 	case PRU_RCVD:
90*4981Swnj 		if (so2 == 0)
91*4981Swnj 			break;
92*4981Swnj #define	rcv (&so->so_rcv)
93*4981Swnj #define snd (&so2->so_snd)
94*4981Swnj 		/*
95*4981Swnj 		 * Transfer resources back to send port
96*4981Swnj 		 * and wakeup any waiting to write.
97*4981Swnj 		 */
98*4981Swnj 		snd->sb_mbmax += rcv->sb_mbmax - rcv->sb_mbcnt;
99*4981Swnj 		rcv->sb_mbmax = rcv->sb_mbcnt;
100*4981Swnj 		snd->sb_hiwat += rcv->sb_hiwat - rcv->sb_cc;
101*4981Swnj 		rcv->sb_hiwat = rcv->sb_cc;
102*4981Swnj 		sbwakeup(snd);
103*4981Swnj #undef snd
104*4981Swnj #undef rcv
1054904Swnj 		break;
1064904Swnj 
1074904Swnj 	case PRU_SEND:
108*4981Swnj #define	rcv (&so2->so_rcv)
109*4981Swnj #define	snd (&so->so_snd)
110*4981Swnj 		/*
111*4981Swnj 		 * Send to paired receive port, and then
112*4981Swnj 		 * give it enough resources to hold what it already has.
113*4981Swnj 		 * Wake up readers.
114*4981Swnj 		 */
115*4981Swnj 		sbappend(rcv, m);
116*4981Swnj 		snd->sb_mbmax -= rcv->sb_mbcnt - rcv->sb_mbmax;
117*4981Swnj 		rcv->sb_mbmax = rcv->sb_mbcnt;
118*4981Swnj 		snd->sb_hiwat -= rcv->sb_cc - rcv->sb_hiwat;
119*4981Swnj 		rcv->sb_hiwat = rcv->sb_cc;
120*4981Swnj 		sbwakeup(rcv);
121*4981Swnj #undef snd
122*4981Swnj #undef rcv
1234904Swnj 		break;
1244904Swnj 
1254904Swnj 	case PRU_ABORT:
1264904Swnj 		return (EOPNOTSUPP);
1274904Swnj 
1284904Swnj 	case PRU_CONTROL:
1294904Swnj 		return (EOPNOTSUPP);
1304904Swnj 
1314904Swnj 	default:
1324927Swnj 		panic("piusrreq");
1334904Swnj 	}
1344904Swnj 	return (0);
1354904Swnj }
136