|
@@ -2065,6 +2065,36 @@ static int unix_shutdown(struct socket *sock, int mode)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+long unix_inq_len(struct sock *sk)
|
|
|
+{
|
|
|
+ struct sk_buff *skb;
|
|
|
+ long amount = 0;
|
|
|
+
|
|
|
+ if (sk->sk_state == TCP_LISTEN)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ spin_lock(&sk->sk_receive_queue.lock);
|
|
|
+ if (sk->sk_type == SOCK_STREAM ||
|
|
|
+ sk->sk_type == SOCK_SEQPACKET) {
|
|
|
+ skb_queue_walk(&sk->sk_receive_queue, skb)
|
|
|
+ amount += skb->len;
|
|
|
+ } else {
|
|
|
+ skb = skb_peek(&sk->sk_receive_queue);
|
|
|
+ if (skb)
|
|
|
+ amount = skb->len;
|
|
|
+ }
|
|
|
+ spin_unlock(&sk->sk_receive_queue.lock);
|
|
|
+
|
|
|
+ return amount;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(unix_inq_len);
|
|
|
+
|
|
|
+long unix_outq_len(struct sock *sk)
|
|
|
+{
|
|
|
+ return sk_wmem_alloc_get(sk);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(unix_outq_len);
|
|
|
+
|
|
|
static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
|
|
{
|
|
|
struct sock *sk = sock->sk;
|
|
@@ -2073,33 +2103,16 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
|
|
|
|
|
switch (cmd) {
|
|
|
case SIOCOUTQ:
|
|
|
- amount = sk_wmem_alloc_get(sk);
|
|
|
+ amount = unix_outq_len(sk);
|
|
|
err = put_user(amount, (int __user *)arg);
|
|
|
break;
|
|
|
case SIOCINQ:
|
|
|
- {
|
|
|
- struct sk_buff *skb;
|
|
|
-
|
|
|
- if (sk->sk_state == TCP_LISTEN) {
|
|
|
- err = -EINVAL;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- spin_lock(&sk->sk_receive_queue.lock);
|
|
|
- if (sk->sk_type == SOCK_STREAM ||
|
|
|
- sk->sk_type == SOCK_SEQPACKET) {
|
|
|
- skb_queue_walk(&sk->sk_receive_queue, skb)
|
|
|
- amount += skb->len;
|
|
|
- } else {
|
|
|
- skb = skb_peek(&sk->sk_receive_queue);
|
|
|
- if (skb)
|
|
|
- amount = skb->len;
|
|
|
- }
|
|
|
- spin_unlock(&sk->sk_receive_queue.lock);
|
|
|
+ amount = unix_inq_len(sk);
|
|
|
+ if (amount < 0)
|
|
|
+ err = amount;
|
|
|
+ else
|
|
|
err = put_user(amount, (int __user *)arg);
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
+ break;
|
|
|
default:
|
|
|
err = -ENOIOCTLCMD;
|
|
|
break;
|