xref: /csrg-svn/sys/kern/uipc_pipe.c (revision 5010)
1*5010Swnj /*	uipc_pipe.c	4.5	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 = {
19*5010Swnj 	SOCK_STREAM,	PF_LOCAL,	0,		PR_CONNREQUIRED|PR_WANTRCVD,
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  */
294927Swnj piconnect(wso, rso)
304904Swnj 	struct socket *wso, *rso;
314904Swnj {
324904Swnj 
334927Swnj COUNT(PICONNECT);
344904Swnj 	if (m_reserve(PIPSIZ) == 0) {
354904Swnj 		u.u_error = ENOBUFS;
364904Swnj 		return (0);
374904Swnj 	}
384904Swnj 	wso->so_proto = rso->so_proto = &pipeproto;
394904Swnj 	wso->so_pcb = (caddr_t)rso;
404904Swnj 	rso->so_pcb = (caddr_t)wso;
414981Swnj 	wso->so_snd.sb_hiwat = PIPSIZ;
424981Swnj 	wso->so_snd.sb_mbmax = 2*PIPSIZ;
434904Swnj 	wso->so_state |= SS_ISCONNECTED|SS_CANTRCVMORE;
444981Swnj 	rso->so_rcv.sb_hiwat = 0;
454981Swnj 	rso->so_rcv.sb_mbmax = 0;
464904Swnj 	rso->so_state |= SS_ISCONNECTED|SS_CANTSENDMORE;
474904Swnj 	return (1);
484904Swnj }
494904Swnj 
504904Swnj /*
514904Swnj  * User requests on pipes and other internally implemented
524904Swnj  * structures.
534904Swnj  */
544916Swnj /*ARGSUSED*/
554927Swnj piusrreq(so, req, m, addr)
564904Swnj 	struct socket *so;
574904Swnj 	int req;
584904Swnj 	struct mbuf *m;
594904Swnj 	caddr_t addr;
604904Swnj {
614904Swnj 	struct socket *so2 = (struct socket *)so->so_pcb;
624904Swnj 
634927Swnj COUNT(PIUSRREQ);
644904Swnj 	switch (req) {
654904Swnj 
664904Swnj 	case PRU_ATTACH:
67*5010Swnj 		break;
68*5010Swnj 
694904Swnj 	case PRU_DETACH:
70*5010Swnj 		so->so_pcb = 0;
714904Swnj 		break;
724904Swnj 
734904Swnj 	case PRU_CONNECT:
744927Swnj 	case PRU_ACCEPT:
754904Swnj 		return (EOPNOTSUPP);
764904Swnj 
774904Swnj 	case PRU_DISCONNECT:
784904Swnj 		if (so2 == 0)
794904Swnj 			return (ENOTCONN);
804904Swnj 		so->so_pcb = 0;
814916Swnj 		soisdisconnected(so);
82*5010Swnj 		soisdisconnected(so2);
834904Swnj 		break;
844904Swnj 
854904Swnj 	case PRU_SHUTDOWN:
864927Swnj 		socantsendmore(so);
874927Swnj 		if (so2)
884927Swnj 			socantrcvmore(so2);
894904Swnj 		break;
904904Swnj 
914904Swnj 	case PRU_RCVD:
924981Swnj 		if (so2 == 0)
934981Swnj 			break;
944981Swnj #define	rcv (&so->so_rcv)
954981Swnj #define snd (&so2->so_snd)
96*5010Swnj /*
97*5010Swnj printf("pru_rcvd in: ");
98*5010Swnj psndrcv(snd, rcv);
99*5010Swnj */
1004981Swnj 		/*
1014981Swnj 		 * Transfer resources back to send port
1024981Swnj 		 * and wakeup any waiting to write.
1034981Swnj 		 */
1044981Swnj 		snd->sb_mbmax += rcv->sb_mbmax - rcv->sb_mbcnt;
1054981Swnj 		rcv->sb_mbmax = rcv->sb_mbcnt;
1064981Swnj 		snd->sb_hiwat += rcv->sb_hiwat - rcv->sb_cc;
1074981Swnj 		rcv->sb_hiwat = rcv->sb_cc;
108*5010Swnj /*
109*5010Swnj printf("pru_rcvd out: ");
110*5010Swnj psndrcv(snd, rcv);
111*5010Swnj */
1124981Swnj 		sbwakeup(snd);
1134981Swnj #undef snd
1144981Swnj #undef rcv
1154904Swnj 		break;
1164904Swnj 
1174904Swnj 	case PRU_SEND:
1184981Swnj #define	rcv (&so2->so_rcv)
1194981Swnj #define	snd (&so->so_snd)
1204981Swnj 		/*
1214981Swnj 		 * Send to paired receive port, and then
1224981Swnj 		 * give it enough resources to hold what it already has.
1234981Swnj 		 * Wake up readers.
1244981Swnj 		 */
125*5010Swnj /*
126*5010Swnj printf("pru_send in: ");
127*5010Swnj psndrcv(snd, rcv);
128*5010Swnj */
1294981Swnj 		sbappend(rcv, m);
1304981Swnj 		snd->sb_mbmax -= rcv->sb_mbcnt - rcv->sb_mbmax;
1314981Swnj 		rcv->sb_mbmax = rcv->sb_mbcnt;
1324981Swnj 		snd->sb_hiwat -= rcv->sb_cc - rcv->sb_hiwat;
1334981Swnj 		rcv->sb_hiwat = rcv->sb_cc;
1344981Swnj 		sbwakeup(rcv);
135*5010Swnj /*
136*5010Swnj printf("pru_send out: ");
137*5010Swnj psndrcv(snd, rcv);
138*5010Swnj */
1394981Swnj #undef snd
1404981Swnj #undef rcv
1414904Swnj 		break;
1424904Swnj 
1434904Swnj 	case PRU_ABORT:
1444904Swnj 		return (EOPNOTSUPP);
1454904Swnj 
1464904Swnj 	case PRU_CONTROL:
1474904Swnj 		return (EOPNOTSUPP);
1484904Swnj 
1494904Swnj 	default:
1504927Swnj 		panic("piusrreq");
1514904Swnj 	}
1524904Swnj 	return (0);
1534904Swnj }
154*5010Swnj 
155*5010Swnj psndrcv(snd, rcv)
156*5010Swnj 	struct sockbuf *snd, *rcv;
157*5010Swnj {
158*5010Swnj 
159*5010Swnj 	printf("snd: (cc,hiwat,mbcnt,mbmax) (%d,%d,%d,%d) ",
160*5010Swnj 	    snd->sb_cc, snd->sb_hiwat, snd->sb_mbcnt, snd->sb_mbmax);
161*5010Swnj 	printf("m %x, m->m_len %d\n", snd->sb_mb, snd->sb_mb ? snd->sb_mb->m_len : 0);
162*5010Swnj 	printf("rcv: (cc,hiwat,mbcnt,mbmax) (%d,%d,%d,%d) ",
163*5010Swnj 	    rcv->sb_cc, rcv->sb_hiwat, rcv->sb_mbcnt, rcv->sb_mbmax);
164*5010Swnj 	printf("m %x, m->m_len %d\n", rcv->sb_mb, rcv->sb_mb ? rcv->sb_mb->m_len : 0);
165*5010Swnj }
166