xref: /csrg-svn/sys/kern/uipc_pipe.c (revision 7180)
1*7180Swnj /*	uipc_pipe.c	4.12	82/06/14	*/
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"
105091Swnj #include "../net/in_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 = {
195167Swnj 	SOCK_STREAM,	PF_UNIX,	0,		PR_CONNREQUIRED|PR_WANTRCVD,
204904Swnj 	0,		0,		0,		0,
215167Swnj 	piusrreq,
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  */
294927Swnj piconnect(wso, rso)
304904Swnj 	struct socket *wso, *rso;
314904Swnj {
324904Swnj 
334927Swnj COUNT(PICONNECT);
34*7180Swnj 	/* when we reserve memory this routine may fail */
354904Swnj 	wso->so_proto = rso->so_proto = &pipeproto;
364904Swnj 	wso->so_pcb = (caddr_t)rso;
374904Swnj 	rso->so_pcb = (caddr_t)wso;
384981Swnj 	wso->so_snd.sb_hiwat = PIPSIZ;
394981Swnj 	wso->so_snd.sb_mbmax = 2*PIPSIZ;
404904Swnj 	wso->so_state |= SS_ISCONNECTED|SS_CANTRCVMORE;
414981Swnj 	rso->so_rcv.sb_hiwat = 0;
424981Swnj 	rso->so_rcv.sb_mbmax = 0;
434904Swnj 	rso->so_state |= SS_ISCONNECTED|SS_CANTSENDMORE;
444904Swnj 	return (1);
454904Swnj }
464904Swnj 
474904Swnj /*
484904Swnj  * User requests on pipes and other internally implemented
494904Swnj  * structures.
504904Swnj  */
514916Swnj /*ARGSUSED*/
524927Swnj piusrreq(so, req, m, addr)
534904Swnj 	struct socket *so;
544904Swnj 	int req;
554904Swnj 	struct mbuf *m;
564904Swnj 	caddr_t addr;
574904Swnj {
584904Swnj 	struct socket *so2 = (struct socket *)so->so_pcb;
594904Swnj 
604927Swnj COUNT(PIUSRREQ);
614904Swnj 	switch (req) {
624904Swnj 
634904Swnj 	case PRU_ATTACH:
645010Swnj 		break;
655010Swnj 
664904Swnj 	case PRU_DETACH:
675010Swnj 		so->so_pcb = 0;
684904Swnj 		break;
694904Swnj 
704904Swnj 	case PRU_CONNECT:
714927Swnj 	case PRU_ACCEPT:
724904Swnj 		return (EOPNOTSUPP);
734904Swnj 
744904Swnj 	case PRU_DISCONNECT:
754904Swnj 		if (so2 == 0)
764904Swnj 			return (ENOTCONN);
774904Swnj 		so->so_pcb = 0;
785021Sroot 		so2->so_pcb = 0;
794916Swnj 		soisdisconnected(so);
805010Swnj 		soisdisconnected(so2);
814904Swnj 		break;
824904Swnj 
834904Swnj 	case PRU_SHUTDOWN:
844927Swnj 		socantsendmore(so);
854927Swnj 		if (so2)
864927Swnj 			socantrcvmore(so2);
874904Swnj 		break;
884904Swnj 
894904Swnj 	case PRU_RCVD:
904981Swnj 		if (so2 == 0)
914981Swnj 			break;
924981Swnj #define	rcv (&so->so_rcv)
934981Swnj #define snd (&so2->so_snd)
944981Swnj 		/*
954981Swnj 		 * Transfer resources back to send port
964981Swnj 		 * and wakeup any waiting to write.
974981Swnj 		 */
984981Swnj 		snd->sb_mbmax += rcv->sb_mbmax - rcv->sb_mbcnt;
994981Swnj 		rcv->sb_mbmax = rcv->sb_mbcnt;
1004981Swnj 		snd->sb_hiwat += rcv->sb_hiwat - rcv->sb_cc;
1014981Swnj 		rcv->sb_hiwat = rcv->sb_cc;
1024981Swnj 		sbwakeup(snd);
1034981Swnj #undef snd
1044981Swnj #undef rcv
1054904Swnj 		break;
1064904Swnj 
1074904Swnj 	case PRU_SEND:
1084981Swnj #define	rcv (&so2->so_rcv)
1094981Swnj #define	snd (&so->so_snd)
1105021Sroot 		if (so2 == 0)
1115021Sroot 			panic("pipe send");
1124981Swnj 		/*
1134981Swnj 		 * Send to paired receive port, and then
1144981Swnj 		 * give it enough resources to hold what it already has.
1154981Swnj 		 * Wake up readers.
1164981Swnj 		 */
1174981Swnj 		sbappend(rcv, m);
1184981Swnj 		snd->sb_mbmax -= rcv->sb_mbcnt - rcv->sb_mbmax;
1194981Swnj 		rcv->sb_mbmax = rcv->sb_mbcnt;
1204981Swnj 		snd->sb_hiwat -= rcv->sb_cc - rcv->sb_hiwat;
1214981Swnj 		rcv->sb_hiwat = rcv->sb_cc;
1224981Swnj 		sbwakeup(rcv);
1234981Swnj #undef snd
1244981Swnj #undef rcv
1254904Swnj 		break;
1264904Swnj 
1274904Swnj 	case PRU_ABORT:
1284904Swnj 		return (EOPNOTSUPP);
1294904Swnj 
1304904Swnj 	case PRU_CONTROL:
1314904Swnj 		return (EOPNOTSUPP);
1324904Swnj 
1334904Swnj 	default:
1344927Swnj 		panic("piusrreq");
1354904Swnj 	}
1364904Swnj 	return (0);
1374904Swnj }
138