xref: /csrg-svn/sys/kern/uipc_pipe.c (revision 4916)
1*4916Swnj /*	uipc_pipe.c	4.2	81/11/16	*/
24904Swnj 
34904Swnj #include "../h/param.h"
44904Swnj #include "../h/dir.h"
54904Swnj #include "../h/user.h"
64904Swnj #include "../h/mbuf.h"
74904Swnj #include "../h/protocol.h"
84904Swnj #include "../h/protosw.h"
94904Swnj #include "../h/socket.h"
104904Swnj #include "../h/socketvar.h"
114904Swnj #include "../h/inaddr.h"
124904Swnj 
134904Swnj int	pi_usrreq();
144904Swnj #define	PIPSIZ	4096
154904Swnj 
164904Swnj /*
174904Swnj  * Code for pipes and other loopback protocols (single machine, that is.)
184904Swnj  */
194904Swnj struct	protosw pipeproto = {
204904Swnj 	SOCK_STREAM,	PF_LOCAL,	0,		PR_CONNREQUIRED,
214904Swnj 	0,		0,		0,		0,
224904Swnj 	pi_usrreq,	0,		0,
234904Swnj 	0,		0,		0,		0
244904Swnj };
254904Swnj 
264904Swnj /*
274904Swnj  * Connect a pipe from wso to rso.  The protocol control block
284904Swnj  * for a pipe is used to store a pointer to the matching socket.
294904Swnj  * Each half of the pipe gets half of the buffer space (half send
304904Swnj  * buffers, half receive buffers).
314904Swnj  */
324904Swnj pi_connect(wso, rso)
334904Swnj 	struct socket *wso, *rso;
344904Swnj {
354904Swnj 
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 pi_splice(pso, so)
534904Swnj 	struct socket *pso, *so;
544904Swnj {
554904Swnj 
564904Swnj 	if (pso->so_proto != &pipeproto) {
574904Swnj 		struct socket *tso;
584904Swnj 		tso = pso; pso = so; so = tso;
594904Swnj 	}
604904Swnj 	if (pso->so_proto != &pipeproto)
614904Swnj 		return (EOPNOTSUPP);
624904Swnj 	/* check types and buffer space */
634904Swnj 	/* merge buffers */
644904Swnj 	return (0);
654904Swnj }
664904Swnj 
674904Swnj /*
684904Swnj  * User requests on pipes and other internally implemented
694904Swnj  * structures.
704904Swnj  */
71*4916Swnj /*ARGSUSED*/
724904Swnj pi_usrreq(so, req, m, addr)
734904Swnj 	struct socket *so;
744904Swnj 	int req;
754904Swnj 	struct mbuf *m;
764904Swnj 	caddr_t addr;
774904Swnj {
784904Swnj 	struct socket *so2 = (struct socket *)so->so_pcb;
794904Swnj 
804904Swnj 	switch (req) {
814904Swnj 
824904Swnj 	case PRU_ATTACH:
834904Swnj 	case PRU_DETACH:
844904Swnj 		break;
854904Swnj 
864904Swnj 	case PRU_CONNECT:
874904Swnj 		return (EOPNOTSUPP);
884904Swnj 
894904Swnj 	case PRU_DISCONNECT:
904904Swnj 		if (so2 == 0)
914904Swnj 			return (ENOTCONN);
924904Swnj 		so->so_pcb = 0;
93*4916Swnj 		soisdisconnected(so);
944904Swnj 		break;
954904Swnj 
964904Swnj 	case PRU_FLUSH:
97*4916Swnj 		return (EOPNOTSUPP);
984904Swnj 
994904Swnj 	case PRU_SHUTDOWN:
1004904Swnj 		so->so_state |= SS_CANTSENDMORE;
101*4916Swnj 		sowwakeup(so);
1024904Swnj 		if (so2) {
1034904Swnj 			so2->so_state |= SS_CANTRCVMORE;
1044904Swnj 			sorwakeup(so2);
1054904Swnj 		}
1064904Swnj 		break;
1074904Swnj 
1084904Swnj 	case PRU_RCVD:
1094904Swnj 		if (so->so_rcv.sb_cc == 0 && so2 && so2->so_snd.sb_cc) {
1104904Swnj 			so->so_rcv.sb_cc = so2->so_snd.sb_cc;
1114904Swnj 			so->so_rcv.sb_mbcnt = so2->so_snd.sb_mbcnt;
1124904Swnj 			so->so_rcv.sb_mb = so2->so_rcv.sb_mb;
1134904Swnj 			so2->so_snd.sb_cc = 0;
1144904Swnj 			so2->so_snd.sb_mbcnt = 0;
1154904Swnj 			so2->so_snd.sb_mb = 0;
1164904Swnj 			sorwakeup(so);
1174904Swnj 			sowwakeup(so2);
1184904Swnj 		}
1194904Swnj 		break;
1204904Swnj 
1214904Swnj 	case PRU_SEND:
1224904Swnj 		sbappend(&so->so_snd, m);
1234904Swnj 		sorwakeup(so2);
1244904Swnj 		break;
1254904Swnj 
1264904Swnj 	case PRU_ABORT:
1274904Swnj 		return (EOPNOTSUPP);
1284904Swnj 
1294904Swnj 	case PRU_CONTROL:
1304904Swnj 		return (EOPNOTSUPP);
1314904Swnj 
1324904Swnj 	default:
1334904Swnj 		panic("pi_usrreq");
1344904Swnj 	}
1354904Swnj 	return (0);
1364904Swnj }
137