Diff below adds SOCK_SEQPACKET support to UNIX sockets. Just like
SOCK_STREAM but with record boundaries like SOCK_DGRAM.
Lightly tested that SOCK_SEQPACKET sockets appear to work as expected.
Feedback/testing suggestions/ok?
Index: uipc_proto.c
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/kern/uipc_proto.c,v
retrieving revision 1.5
diff -u -p -r1.5 uipc_proto.c
--- uipc_proto.c 5 Apr 2011 19:54:36 -0000 1.5
+++ uipc_proto.c 23 Jun 2011 21:17:55 -0000
@@ -55,6 +55,11 @@ struct protosw unixsw[] = {
uipc_usrreq,
0, 0, 0, 0,
},
+{ SOCK_SEQPACKET,&unixdomain, PF_LOCAL,
PR_ATOMIC|PR_CONNREQUIRED|PR_WANTRCVD|PR_RIGHTS,
+ 0, 0, 0, 0,
+ uipc_usrreq,
+ 0, 0, 0, 0,
+},
{ SOCK_DGRAM, &unixdomain, PF_LOCAL, PR_ATOMIC|PR_ADDR|PR_RIGHTS,
0, 0, 0, 0,
uipc_usrreq,
Index: uipc_usrreq.c
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.51
diff -u -p -r1.51 uipc_usrreq.c
--- uipc_usrreq.c 17 May 2011 00:17:01 -0000 1.51
+++ uipc_usrreq.c 23 Jun 2011 21:38:17 -0000
@@ -52,7 +52,7 @@
* Unix communications domain.
*
* TODO:
- * SEQPACKET, RDM
+ * RDM
* rethink name space problems
* need a proper out-of-band
*/
@@ -142,6 +142,7 @@ uipc_usrreq(struct socket *so, int req,
/*NOTREACHED*/
case SOCK_STREAM:
+ case SOCK_SEQPACKET:
#define rcv (&so->so_rcv)
#define snd (&so2->so_snd)
if (unp->unp_conn == NULL)
@@ -204,6 +205,7 @@ uipc_usrreq(struct socket *so, int req,
}
case SOCK_STREAM:
+ case SOCK_SEQPACKET:
#define rcv (&so2->so_rcv)
#define snd (&so->so_snd)
if (so->so_state & SS_CANTSENDMORE) {
@@ -223,7 +225,9 @@ uipc_usrreq(struct socket *so, int req,
if (control) {
if (sbappendcontrol(rcv, m, control))
control = NULL;
- } else
+ } else if (so->so_type == SOCK_SEQPACKET)
+ sbappendrecord(rcv, m);
+ else
sbappend(rcv, m);
snd->sb_mbmax -=
rcv->sb_mbcnt - unp->unp_conn->unp_mbcnt;
@@ -250,9 +254,17 @@ uipc_usrreq(struct socket *so, int req,
case PRU_SENSE:
((struct stat *) m)->st_blksize = so->so_snd.sb_hiwat;
- if (so->so_type == SOCK_STREAM && unp->unp_conn != NULL) {
- so2 = unp->unp_conn->unp_socket;
- ((struct stat *) m)->st_blksize += so2->so_rcv.sb_cc;
+ switch (so->so_type) {
+ case SOCK_STREAM:
+ case SOCK_SEQPACKET:
+ if (unp->unp_conn != NULL) {
+ so2 = unp->unp_conn->unp_socket;
+ ((struct stat *) m)->st_blksize +=
+ so2->so_rcv.sb_cc;
+ }
+ break;
+ default:
+ break;
}
((struct stat *) m)->st_dev = NODEV;
if (unp->unp_ino == 0)
@@ -328,6 +340,7 @@ unp_attach(struct socket *so)
switch (so->so_type) {
case SOCK_STREAM:
+ case SOCK_SEQPACKET:
error = soreserve(so, unpst_sendspace, unpst_recvspace);
break;
@@ -511,6 +524,7 @@ unp_connect2(struct socket *so, struct s
break;
case SOCK_STREAM:
+ case SOCK_SEQPACKET:
unp2->unp_conn = unp;
soisconnected(so);
soisconnected(so2);
@@ -551,6 +565,7 @@ unp_disconnect(struct unpcb *unp)
break;
case SOCK_STREAM:
+ case SOCK_SEQPACKET:
soisdisconnected(unp->unp_socket);
unp2->unp_conn = NULL;
soisdisconnected(unp2->unp_socket);
@@ -570,9 +585,15 @@ unp_shutdown(struct unpcb *unp)
{
struct socket *so;
- if (unp->unp_socket->so_type == SOCK_STREAM && unp->unp_conn &&
- (so = unp->unp_conn->unp_socket))
- socantrcvmore(so);
+ switch (unp->unp_socket->so_type) {
+ case SOCK_STREAM:
+ case SOCK_SEQPACKET:
+ if (unp->unp_conn && (so = unp->unp_conn->unp_socket))
+ socantrcvmore(so);
+ break;
+ default:
+ break;
+ }
}
void