--- linux-2.6.3/net/unix/af_unix.c 2004-02-17 20:58:33.000000000 -0700 +++ linux-2.6.3-seqpacket/net/unix/af_unix.c 2004-02-27 23:25:23.000000000 -0700 @@ -377,7 +377,7 @@ skpair=unix_peer(sk); if (skpair!=NULL) { - if (sk->sk_type == SOCK_STREAM) { + if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) { unix_state_wlock(skpair); /* No more writes */ skpair->sk_shutdown = SHUTDOWN_MASK; @@ -435,8 +435,8 @@ struct unix_sock *u = unix_sk(sk); err = -EOPNOTSUPP; - if (sock->type!=SOCK_STREAM) - goto out; /* Only stream sockets accept */ + if (sock->type!=SOCK_STREAM && sock->type!=SOCK_SEQPACKET) + goto out; /* Only stream/seqpacket sockets accept */ err = -EINVAL; if (!u->addr) goto out; /* No listens on an unbound socket */ @@ -461,6 +461,7 @@ extern struct proto_ops unix_stream_ops; extern struct proto_ops unix_dgram_ops; +extern struct proto_ops unix_seqpacket_ops; static struct sock * unix_create1(struct socket *sock) { @@ -515,6 +516,9 @@ case SOCK_DGRAM: sock->ops = &unix_dgram_ops; break; + case SOCK_SEQPACKET: + sock->ops = &unix_seqpacket_ops; + break; default: return -ESOCKTNOSUPPORT; } @@ -982,7 +986,7 @@ sock_hold(sk); unix_peer(newsk) = sk; newsk->sk_state = TCP_ESTABLISHED; - newsk->sk_type = SOCK_STREAM; + newsk->sk_type = sk->sk_type; newsk->sk_peercred.pid = current->tgid; newsk->sk_peercred.uid = current->euid; newsk->sk_peercred.gid = current->egid; @@ -1066,7 +1070,7 @@ int err; err = -EOPNOTSUPP; - if (sock->type!=SOCK_STREAM) + if (sock->type!=SOCK_STREAM && sock->type!=SOCK_SEQPACKET) goto out; err = -EINVAL; @@ -1711,7 +1715,9 @@ unix_state_wunlock(sk); sk->sk_state_change(sk); - if (other && sk->sk_type == SOCK_STREAM) { + if (other && + (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) { + int peer_mode = 0; if (mode&RCV_SHUTDOWN) @@ -1791,7 +1797,7 @@ mask |= POLLIN | POLLRDNORM; /* Connection-based need to check for termination and startup */ - if (sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_CLOSE) + if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) && sk->sk_state == TCP_CLOSE) mask |= POLLHUP; /* @@ -1967,6 +1973,27 @@ .sendpage = sock_no_sendpage, }; +struct proto_ops unix_seqpacket_ops = { + .family = PF_UNIX, + .owner = THIS_MODULE, + .release = unix_release, + .bind = unix_bind, + .connect = unix_stream_connect, + .socketpair = unix_socketpair, + .accept = unix_accept, + .getname = unix_getname, + .poll = datagram_poll, + .ioctl = unix_ioctl, + .listen = unix_listen, + .shutdown = unix_shutdown, + .setsockopt = sock_no_setsockopt, + .getsockopt = sock_no_getsockopt, + .sendmsg = unix_dgram_sendmsg, + .recvmsg = unix_dgram_recvmsg, + .mmap = sock_no_mmap, + .sendpage = sock_no_sendpage, +}; + struct net_proto_family unix_family_ops = { .family = PF_UNIX, .create = unix_create,