Staging: et131x: Clean up the half duplex control reg types
[safe/jmp/linux-2.6] / net / unix / af_unix.c
index fc3ebb9..f255119 100644 (file)
@@ -621,7 +621,8 @@ out:
        return sk;
 }
 
-static int unix_create(struct net *net, struct socket *sock, int protocol)
+static int unix_create(struct net *net, struct socket *sock, int protocol,
+                      int kern)
 {
        if (protocol && protocol != PF_UNIX)
                return -EPROTONOSUPPORT;
@@ -1032,8 +1033,8 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
                goto out;
        addr_len = err;
 
-       if (test_bit(SOCK_PASSCRED, &sock->flags)
-               && !u->addr && (err = unix_autobind(sock)) != 0)
+       if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr &&
+           (err = unix_autobind(sock)) != 0)
                goto out;
 
        timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
@@ -1074,6 +1075,8 @@ restart:
        err = -ECONNREFUSED;
        if (other->sk_state != TCP_LISTEN)
                goto out_unlock;
+       if (other->sk_shutdown & RCV_SHUTDOWN)
+               goto out_unlock;
 
        if (unix_recvq_full(other)) {
                err = -EAGAIN;
@@ -1256,7 +1259,7 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_
 {
        struct sock *sk = sock->sk;
        struct unix_sock *u;
-       struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
+       DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, uaddr);
        int err = 0;
 
        if (peer) {
@@ -1375,8 +1378,8 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
                        goto out;
        }
 
-       if (test_bit(SOCK_PASSCRED, &sock->flags)
-               && !u->addr && (err = unix_autobind(sock)) != 0)
+       if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr
+           && (err = unix_autobind(sock)) != 0)
                goto out;
 
        err = -EMSGSIZE;
@@ -1501,6 +1504,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
        struct sk_buff *skb;
        int sent = 0;
        struct scm_cookie tmp_scm;
+       bool fds_sent = false;
 
        if (NULL == siocb->scm)
                siocb->scm = &tmp_scm;
@@ -1562,12 +1566,14 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
                size = min_t(int, size, skb_tailroom(skb));
 
                memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
-               if (siocb->scm->fp) {
+               /* Only send the fds in the first buffer */
+               if (siocb->scm->fp && !fds_sent) {
                        err = unix_attach_fds(siocb->scm, skb);
                        if (err) {
                                kfree_skb(skb);
                                goto out_err;
                        }
+                       fds_sent = true;
                }
 
                err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
@@ -2211,7 +2217,7 @@ static const struct file_operations unix_seq_fops = {
 
 #endif
 
-static struct net_proto_family unix_family_ops = {
+static const struct net_proto_family unix_family_ops = {
        .family = PF_UNIX,
        .create = unix_create,
        .owner  = THIS_MODULE,