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
This commit is contained in:
dchagin 2009-05-11 13:50:42 +00:00
parent 4f4faf9d43
commit ebcb202672
2 changed files with 41 additions and 1 deletions

View File

@ -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

View File

@ -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);