xref: /csrg-svn/sys/kern/uipc_pipe.c (revision 4927)
1*4927Swnj /*	uipc_pipe.c	4.3	81/11/18	*/
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"
10*4927Swnj #include "../net/inet_systm.h"		/* XXX */
114904Swnj 
12*4927Swnj 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,
21*4927Swnj 	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  */
31*4927Swnj piconnect(wso, rso)
324904Swnj 	struct socket *wso, *rso;
334904Swnj {
344904Swnj 
35*4927Swnj 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;
434904Swnj 	wso->so_snd.sb_hiwat = PIPSIZ/2;
444904Swnj 	wso->so_snd.sb_mbcnt = PIPSIZ;
454904Swnj 	wso->so_state |= SS_ISCONNECTED|SS_CANTRCVMORE;
464904Swnj 	rso->so_rcv.sb_hiwat = PIPSIZ/2;
474904Swnj 	rso->so_rcv.sb_mbcnt = PIPSIZ;
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*/
57*4927Swnj 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 
65*4927Swnj COUNT(PIUSRREQ);
664904Swnj 	switch (req) {
674904Swnj 
684904Swnj 	case PRU_ATTACH:
694904Swnj 	case PRU_DETACH:
704904Swnj 		break;
714904Swnj 
724904Swnj 	case PRU_CONNECT:
73*4927Swnj 	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:
84*4927Swnj 		socantsendmore(so);
85*4927Swnj 		if (so2)
86*4927Swnj 			socantrcvmore(so2);
874904Swnj 		break;
884904Swnj 
894904Swnj 	case PRU_RCVD:
904904Swnj 		if (so->so_rcv.sb_cc == 0 && so2 && so2->so_snd.sb_cc) {
914904Swnj 			so->so_rcv.sb_cc = so2->so_snd.sb_cc;
924904Swnj 			so->so_rcv.sb_mbcnt = so2->so_snd.sb_mbcnt;
934904Swnj 			so->so_rcv.sb_mb = so2->so_rcv.sb_mb;
944904Swnj 			so2->so_snd.sb_cc = 0;
954904Swnj 			so2->so_snd.sb_mbcnt = 0;
964904Swnj 			so2->so_snd.sb_mb = 0;
974904Swnj 			sorwakeup(so);
984904Swnj 			sowwakeup(so2);
994904Swnj 		}
1004904Swnj 		break;
1014904Swnj 
1024904Swnj 	case PRU_SEND:
1034904Swnj 		sbappend(&so->so_snd, m);
1044904Swnj 		sorwakeup(so2);
1054904Swnj 		break;
1064904Swnj 
1074904Swnj 	case PRU_ABORT:
1084904Swnj 		return (EOPNOTSUPP);
1094904Swnj 
1104904Swnj 	case PRU_CONTROL:
1114904Swnj 		return (EOPNOTSUPP);
1124904Swnj 
1134904Swnj 	default:
114*4927Swnj 		panic("piusrreq");
1154904Swnj 	}
1164904Swnj 	return (0);
1174904Swnj }
118