diff options
-rw-r--r-- | include/net/compat.h | 4 | ||||
-rw-r--r-- | net/compat.c | 19 |
2 files changed, 22 insertions, 1 deletions
diff --git a/include/net/compat.h b/include/net/compat.h index 290bab46d457..8662b8f43df5 100644 --- a/include/net/compat.h +++ b/include/net/compat.h | |||
@@ -23,6 +23,9 @@ struct compat_cmsghdr { | |||
23 | compat_int_t cmsg_type; | 23 | compat_int_t cmsg_type; |
24 | }; | 24 | }; |
25 | 25 | ||
26 | struct sock; | ||
27 | extern int compat_sock_get_timestamp(struct sock *, struct timeval __user *); | ||
28 | |||
26 | #else /* defined(CONFIG_COMPAT) */ | 29 | #else /* defined(CONFIG_COMPAT) */ |
27 | #define compat_msghdr msghdr /* to avoid compiler warnings */ | 30 | #define compat_msghdr msghdr /* to avoid compiler warnings */ |
28 | #endif /* defined(CONFIG_COMPAT) */ | 31 | #endif /* defined(CONFIG_COMPAT) */ |
@@ -34,7 +37,6 @@ extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsi | |||
34 | extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *); | 37 | extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *); |
35 | extern int put_cmsg_compat(struct msghdr*, int, int, int, void *); | 38 | extern int put_cmsg_compat(struct msghdr*, int, int, int, void *); |
36 | 39 | ||
37 | struct sock; | ||
38 | extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int); | 40 | extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int); |
39 | 41 | ||
40 | #endif /* NET_COMPAT_H */ | 42 | #endif /* NET_COMPAT_H */ |
diff --git a/net/compat.c b/net/compat.c index 13177a1a4b39..8fd37cd7b501 100644 --- a/net/compat.c +++ b/net/compat.c | |||
@@ -543,6 +543,25 @@ static int compat_sock_getsockopt(struct socket *sock, int level, int optname, | |||
543 | return sock_getsockopt(sock, level, optname, optval, optlen); | 543 | return sock_getsockopt(sock, level, optname, optval, optlen); |
544 | } | 544 | } |
545 | 545 | ||
546 | int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) | ||
547 | { | ||
548 | struct compat_timeval __user *ctv = | ||
549 | (struct compat_timeval __user*) userstamp; | ||
550 | int err = -ENOENT; | ||
551 | |||
552 | if (!sock_flag(sk, SOCK_TIMESTAMP)) | ||
553 | sock_enable_timestamp(sk); | ||
554 | if (sk->sk_stamp.tv_sec == -1) | ||
555 | return err; | ||
556 | if (sk->sk_stamp.tv_sec == 0) | ||
557 | do_gettimeofday(&sk->sk_stamp); | ||
558 | if (put_user(sk->sk_stamp.tv_sec, &ctv->tv_sec) || | ||
559 | put_user(sk->sk_stamp.tv_usec, &ctv->tv_usec)) | ||
560 | err = -EFAULT; | ||
561 | return err; | ||
562 | } | ||
563 | EXPORT_SYMBOL(compat_sock_get_timestamp); | ||
564 | |||
546 | asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, | 565 | asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, |
547 | char __user *optval, int __user *optlen) | 566 | char __user *optval, int __user *optlen) |
548 | { | 567 | { |