aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDmitry Chagin <dchagin@FreeBSD.org>2009-05-11 13:50:42 +0000
committerDmitry Chagin <dchagin@FreeBSD.org>2009-05-11 13:50:42 +0000
commit03cc95d21a36ab2a353cbbfbcfbc5d83e4f4a6e1 (patch)
tree8fe6bfbface75f17fd918d0c44f41af9c120ec4f /sys
parent3980a435a2f6b57287c1d66bcb9c30b3d003b1e5 (diff)
downloadsrc-03cc95d21a36ab2a353cbbfbcfbc5d83e4f4a6e1.tar.gz
src-03cc95d21a36ab2a353cbbfbcfbc5d83e4f4a6e1.zip
Translate l_timeval arg to native struct timeval in
linux_setsockopt()/linux_getsockopt() for SO_RCVTIMEO, SO_SNDTIMEO opts as l_timeval has MD members. Remove bogus __packed attribute from l_timeval struct on __amd64__. PR: kern/134276 Submitted by: Thomas Mueller <tmueller sysgo com> Approved by: kib (mentor) MFC after: 2 weeks
Notes
Notes: svn path=/head/; revision=191989
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/linux32/linux.h2
-rw-r--r--sys/compat/linux/linux_socket.c40
2 files changed, 41 insertions, 1 deletions
diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h
index 78abf63f38a7..59970fdd3ce9 100644
--- a/sys/amd64/linux32/linux.h
+++ b/sys/amd64/linux32/linux.h
@@ -96,7 +96,7 @@ typedef struct {
typedef struct {
l_time_t tv_sec;
l_suseconds_t tv_usec;
-} __packed l_timeval;
+} l_timeval;
#define l_fd_set fd_set
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index 7df87e6e1de8..bb2090c77725 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -1278,6 +1278,8 @@ linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args)
caddr_t val;
int valsize;
} */ bsd_args;
+ l_timeval linux_tv;
+ struct timeval tv;
int error, name;
bsd_args.s = args->s;
@@ -1285,6 +1287,23 @@ linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args)
switch (bsd_args.level) {
case SOL_SOCKET:
name = linux_to_bsd_so_sockopt(args->optname);
+ switch (name) {
+ case SO_RCVTIMEO:
+ /* FALLTHROUGH */
+ case SO_SNDTIMEO:
+ error = copyin(PTRIN(args->optval), &linux_tv,
+ sizeof(linux_tv));
+ if (error)
+ return (error);
+ tv.tv_sec = linux_tv.tv_sec;
+ tv.tv_usec = linux_tv.tv_usec;
+ return (kern_setsockopt(td, args->s, bsd_args.level,
+ name, &tv, UIO_SYSSPACE, sizeof(tv)));
+ /* NOTREACHED */
+ break;
+ default:
+ break;
+ }
break;
case IPPROTO_IP:
name = linux_to_bsd_ip_sockopt(args->optname);
@@ -1333,6 +1352,9 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
caddr_t val;
int *avalsize;
} */ bsd_args;
+ l_timeval linux_tv;
+ struct timeval tv;
+ socklen_t tv_len;
int error, name;
bsd_args.s = args->s;
@@ -1340,6 +1362,24 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
switch (bsd_args.level) {
case SOL_SOCKET:
name = linux_to_bsd_so_sockopt(args->optname);
+ switch (name) {
+ case SO_RCVTIMEO:
+ /* FALLTHROUGH */
+ case SO_SNDTIMEO:
+ tv_len = sizeof(tv);
+ error = kern_getsockopt(td, args->s, bsd_args.level,
+ name, &tv, UIO_SYSSPACE, &tv_len);
+ if (error)
+ return (error);
+ linux_tv.tv_sec = tv.tv_sec;
+ linux_tv.tv_usec = tv.tv_usec;
+ return (copyout(&linux_tv, PTRIN(args->optval),
+ sizeof(linux_tv)));
+ /* NOTREACHED */
+ break;
+ default:
+ break;
+ }
break;
case IPPROTO_IP:
name = linux_to_bsd_ip_sockopt(args->optname);