wext: let get_wireless_stats() sleep
[safe/jmp/linux-2.6] / net / compat.c
index a3a2ba0..a407c3a 100644 (file)
@@ -216,7 +216,7 @@ Efault:
 int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data)
 {
        struct compat_timeval ctv;
-       struct compat_timespec cts;
+       struct compat_timespec cts[3];
        struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
        struct compat_cmsghdr cmhdr;
        int cmlen;
@@ -233,12 +233,17 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat
                data = &ctv;
                len = sizeof(ctv);
        }
-       if (level == SOL_SOCKET && type == SCM_TIMESTAMPNS) {
+       if (level == SOL_SOCKET &&
+           (type == SCM_TIMESTAMPNS || type == SCM_TIMESTAMPING)) {
+               int count = type == SCM_TIMESTAMPNS ? 1 : 3;
+               int i;
                struct timespec *ts = (struct timespec *)data;
-               cts.tv_sec = ts->tv_sec;
-               cts.tv_nsec = ts->tv_nsec;
+               for (i = 0; i < count; i++) {
+                       cts[i].tv_sec = ts[i].tv_sec;
+                       cts[i].tv_nsec = ts[i].tv_nsec;
+               }
                data = &cts;
-               len = sizeof(cts);
+               len = sizeof(cts[0]) * count;
        }
 
        cmlen = CMSG_COMPAT_LEN(len);
@@ -326,7 +331,7 @@ struct compat_sock_fprog {
 };
 
 static int do_set_attach_filter(struct socket *sock, int level, int optname,
-                               char __user *optval, int optlen)
+                               char __user *optval, unsigned int optlen)
 {
        struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval;
        struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog));
@@ -346,7 +351,7 @@ static int do_set_attach_filter(struct socket *sock, int level, int optname,
 }
 
 static int do_set_sock_timeout(struct socket *sock, int level,
-               int optname, char __user *optval, int optlen)
+               int optname, char __user *optval, unsigned int optlen)
 {
        struct compat_timeval __user *up = (struct compat_timeval __user *) optval;
        struct timeval ktime;
@@ -368,7 +373,7 @@ static int do_set_sock_timeout(struct socket *sock, int level,
 }
 
 static int compat_sock_setsockopt(struct socket *sock, int level, int optname,
-                               char __user *optval, int optlen)
+                               char __user *optval, unsigned int optlen)
 {
        if (optname == SO_ATTACH_FILTER)
                return do_set_attach_filter(sock, level, optname,
@@ -380,7 +385,7 @@ static int compat_sock_setsockopt(struct socket *sock, int level, int optname,
 }
 
 asmlinkage long compat_sys_setsockopt(int fd, int level, int optname,
-                               char __user *optval, int optlen)
+                               char __user *optval, unsigned int optlen)
 {
        int err;
        struct socket *sock;
@@ -455,7 +460,7 @@ int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)
        struct timeval tv;
 
        if (!sock_flag(sk, SOCK_TIMESTAMP))
-               sock_enable_timestamp(sk);
+               sock_enable_timestamp(sk, SOCK_TIMESTAMP);
        tv = ktime_to_timeval(sk->sk_stamp);
        if (tv.tv_sec == -1)
                return err;
@@ -479,7 +484,7 @@ int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *usersta
        struct timespec ts;
 
        if (!sock_flag(sk, SOCK_TIMESTAMP))
-               sock_enable_timestamp(sk);
+               sock_enable_timestamp(sk, SOCK_TIMESTAMP);
        ts = ktime_to_timespec(sk->sk_stamp);
        if (ts.tv_sec == -1)
                return err;
@@ -553,8 +558,8 @@ struct compat_group_filter {
 
 
 int compat_mc_setsockopt(struct sock *sock, int level, int optname,
-       char __user *optval, int optlen,
-       int (*setsockopt)(struct sock *,int,int,char __user *,int))
+       char __user *optval, unsigned int optlen,
+       int (*setsockopt)(struct sock *,int,int,char __user *,unsigned int))
 {
        char __user     *koptval = optval;
        int             koptlen = optlen;
@@ -738,6 +743,18 @@ asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, uns
        return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
 }
 
+asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned flags)
+{
+       return sys_recv(fd, buf, len, flags | MSG_CMSG_COMPAT);
+}
+
+asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, size_t len,
+                                   unsigned flags, struct sockaddr __user *addr,
+                                   int __user *addrlen)
+{
+       return sys_recvfrom(fd, buf, len, flags | MSG_CMSG_COMPAT, addr, addrlen);
+}
+
 asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
 {
        int ret;
@@ -783,10 +800,11 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
                ret = sys_sendto(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4]), a[5]);
                break;
        case SYS_RECV:
-               ret = sys_recv(a0, compat_ptr(a1), a[2], a[3]);
+               ret = compat_sys_recv(a0, compat_ptr(a1), a[2], a[3]);
                break;
        case SYS_RECVFROM:
-               ret = sys_recvfrom(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4]), compat_ptr(a[5]));
+               ret = compat_sys_recvfrom(a0, compat_ptr(a1), a[2], a[3],
+                                         compat_ptr(a[4]), compat_ptr(a[5]));
                break;
        case SYS_SHUTDOWN:
                ret = sys_shutdown(a0,a1);