aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/af_unix.h3
-rw-r--r--net/unix/af_unix.c59
2 files changed, 39 insertions, 23 deletions
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 63b17816e0ba..5a4e29b168c9 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -66,6 +66,9 @@ struct unix_sock {
66 66
67#define peer_wait peer_wq.wait 67#define peer_wait peer_wq.wait
68 68
69long unix_inq_len(struct sock *sk);
70long unix_outq_len(struct sock *sk);
71
69#ifdef CONFIG_SYSCTL 72#ifdef CONFIG_SYSCTL
70extern int unix_sysctl_register(struct net *net); 73extern int unix_sysctl_register(struct net *net);
71extern void unix_sysctl_unregister(struct net *net); 74extern void unix_sysctl_unregister(struct net *net);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index e1b9358a211d..7cc3d7b23d1c 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -2065,6 +2065,36 @@ static int unix_shutdown(struct socket *sock, int mode)
2065 return 0; 2065 return 0;
2066} 2066}
2067 2067
2068long unix_inq_len(struct sock *sk)
2069{
2070 struct sk_buff *skb;
2071 long amount = 0;
2072
2073 if (sk->sk_state == TCP_LISTEN)
2074 return -EINVAL;
2075
2076 spin_lock(&sk->sk_receive_queue.lock);
2077 if (sk->sk_type == SOCK_STREAM ||
2078 sk->sk_type == SOCK_SEQPACKET) {
2079 skb_queue_walk(&sk->sk_receive_queue, skb)
2080 amount += skb->len;
2081 } else {
2082 skb = skb_peek(&sk->sk_receive_queue);
2083 if (skb)
2084 amount = skb->len;
2085 }
2086 spin_unlock(&sk->sk_receive_queue.lock);
2087
2088 return amount;
2089}
2090EXPORT_SYMBOL_GPL(unix_inq_len);
2091
2092long unix_outq_len(struct sock *sk)
2093{
2094 return sk_wmem_alloc_get(sk);
2095}
2096EXPORT_SYMBOL_GPL(unix_outq_len);
2097
2068static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 2098static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2069{ 2099{
2070 struct sock *sk = sock->sk; 2100 struct sock *sk = sock->sk;
@@ -2073,33 +2103,16 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2073 2103
2074 switch (cmd) { 2104 switch (cmd) {
2075 case SIOCOUTQ: 2105 case SIOCOUTQ:
2076 amount = sk_wmem_alloc_get(sk); 2106 amount = unix_outq_len(sk);
2077 err = put_user(amount, (int __user *)arg); 2107 err = put_user(amount, (int __user *)arg);
2078 break; 2108 break;
2079 case SIOCINQ: 2109 case SIOCINQ:
2080 { 2110 amount = unix_inq_len(sk);
2081 struct sk_buff *skb; 2111 if (amount < 0)
2082 2112 err = amount;
2083 if (sk->sk_state == TCP_LISTEN) { 2113 else
2084 err = -EINVAL;
2085 break;
2086 }
2087
2088 spin_lock(&sk->sk_receive_queue.lock);
2089 if (sk->sk_type == SOCK_STREAM ||
2090 sk->sk_type == SOCK_SEQPACKET) {
2091 skb_queue_walk(&sk->sk_receive_queue, skb)
2092 amount += skb->len;
2093 } else {
2094 skb = skb_peek(&sk->sk_receive_queue);
2095 if (skb)
2096 amount = skb->len;
2097 }
2098 spin_unlock(&sk->sk_receive_queue.lock);
2099 err = put_user(amount, (int __user *)arg); 2114 err = put_user(amount, (int __user *)arg);
2100 break; 2115 break;
2101 }
2102
2103 default: 2116 default:
2104 err = -ENOIOCTLCMD; 2117 err = -ENOIOCTLCMD;
2105 break; 2118 break;