Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linux/linux_socket.c
Show First 20 Lines • Show All 1,465 Lines • ▼ Show 20 Lines | linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args) | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) | linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) | ||||
{ | { | ||||
struct getsockopt_args /* { | |||||
int s; | |||||
int level; | |||||
int name; | |||||
caddr_t val; | |||||
int *avalsize; | |||||
} */ bsd_args; | |||||
l_timeval linux_tv; | l_timeval linux_tv; | ||||
struct timeval tv; | struct timeval tv; | ||||
socklen_t tv_len, xulen, len; | socklen_t tv_len, xulen, len; | ||||
struct l_sockaddr *lsa; | struct l_sockaddr *lsa; | ||||
struct sockaddr *sa; | struct sockaddr *sa; | ||||
struct xucred xu; | struct xucred xu; | ||||
struct l_ucred lxu; | struct l_ucred lxu; | ||||
int error, name, newval; | int error, level, name, newval; | ||||
bsd_args.s = args->s; | level = linux_to_bsd_sockopt_level(args->level); | ||||
bsd_args.level = linux_to_bsd_sockopt_level(args->level); | switch (level) { | ||||
switch (bsd_args.level) { | |||||
case SOL_SOCKET: | case SOL_SOCKET: | ||||
name = linux_to_bsd_so_sockopt(args->optname); | name = linux_to_bsd_so_sockopt(args->optname); | ||||
switch (name) { | switch (name) { | ||||
case SO_RCVTIMEO: | case SO_RCVTIMEO: | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case SO_SNDTIMEO: | case SO_SNDTIMEO: | ||||
tv_len = sizeof(tv); | tv_len = sizeof(tv); | ||||
error = kern_getsockopt(td, args->s, bsd_args.level, | error = kern_getsockopt(td, args->s, level, | ||||
name, &tv, UIO_SYSSPACE, &tv_len); | name, &tv, UIO_SYSSPACE, &tv_len); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
linux_tv.tv_sec = tv.tv_sec; | linux_tv.tv_sec = tv.tv_sec; | ||||
linux_tv.tv_usec = tv.tv_usec; | linux_tv.tv_usec = tv.tv_usec; | ||||
return (copyout(&linux_tv, PTRIN(args->optval), | return (copyout(&linux_tv, PTRIN(args->optval), | ||||
sizeof(linux_tv))); | sizeof(linux_tv))); | ||||
/* NOTREACHED */ | /* NOTREACHED */ | ||||
case LOCAL_PEERCRED: | case LOCAL_PEERCRED: | ||||
if (args->optlen < sizeof(lxu)) | if (args->optlen < sizeof(lxu)) | ||||
return (EINVAL); | return (EINVAL); | ||||
/* | /* | ||||
* LOCAL_PEERCRED is not served at the SOL_SOCKET level, | * LOCAL_PEERCRED is not served at the SOL_SOCKET level, | ||||
* but by the Unix socket's level 0. | * but by the Unix socket's level 0. | ||||
*/ | */ | ||||
bsd_args.level = 0; | level = 0; | ||||
xulen = sizeof(xu); | xulen = sizeof(xu); | ||||
error = kern_getsockopt(td, args->s, bsd_args.level, | error = kern_getsockopt(td, args->s, level, | ||||
name, &xu, UIO_SYSSPACE, &xulen); | name, &xu, UIO_SYSSPACE, &xulen); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
lxu.pid = xu.cr_pid; | lxu.pid = xu.cr_pid; | ||||
lxu.uid = xu.cr_uid; | lxu.uid = xu.cr_uid; | ||||
lxu.gid = xu.cr_gid; | lxu.gid = xu.cr_gid; | ||||
return (copyout(&lxu, PTRIN(args->optval), sizeof(lxu))); | return (copyout(&lxu, PTRIN(args->optval), sizeof(lxu))); | ||||
/* NOTREACHED */ | /* NOTREACHED */ | ||||
case SO_ERROR: | case SO_ERROR: | ||||
len = sizeof(newval); | len = sizeof(newval); | ||||
error = kern_getsockopt(td, args->s, bsd_args.level, | error = kern_getsockopt(td, args->s, level, | ||||
name, &newval, UIO_SYSSPACE, &len); | name, &newval, UIO_SYSSPACE, &len); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
newval = -SV_ABI_ERRNO(td->td_proc, newval); | newval = -SV_ABI_ERRNO(td->td_proc, newval); | ||||
return (copyout(&newval, PTRIN(args->optval), len)); | return (copyout(&newval, PTRIN(args->optval), len)); | ||||
/* NOTREACHED */ | /* NOTREACHED */ | ||||
default: | default: | ||||
break; | break; | ||||
Show All 10 Lines | case IPPROTO_TCP: | ||||
break; | break; | ||||
default: | default: | ||||
name = -1; | name = -1; | ||||
break; | break; | ||||
} | } | ||||
if (name == -1) | if (name == -1) | ||||
return (EINVAL); | return (EINVAL); | ||||
bsd_args.name = name; | |||||
bsd_args.avalsize = PTRIN(args->optlen); | |||||
if (name == IPV6_NEXTHOP) { | if (name == IPV6_NEXTHOP) { | ||||
error = copyin(PTRIN(args->optlen), &len, sizeof(len)); | error = copyin(PTRIN(args->optlen), &len, sizeof(len)); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
sa = malloc(len, M_SONAME, M_WAITOK); | sa = malloc(len, M_SONAME, M_WAITOK); | ||||
error = kern_getsockopt(td, args->s, bsd_args.level, | error = kern_getsockopt(td, args->s, level, | ||||
name, sa, UIO_SYSSPACE, &len); | name, sa, UIO_SYSSPACE, &len); | ||||
if (error != 0) | if (error != 0) | ||||
goto out; | goto out; | ||||
error = bsd_to_linux_sockaddr(sa, &lsa, len); | error = bsd_to_linux_sockaddr(sa, &lsa, len); | ||||
if (error == 0) | if (error == 0) | ||||
error = copyout(lsa, PTRIN(args->optval), len); | error = copyout(lsa, PTRIN(args->optval), len); | ||||
free(lsa, M_SONAME); | free(lsa, M_SONAME); | ||||
if (error == 0) | if (error == 0) | ||||
error = copyout(&len, PTRIN(args->optlen), | error = copyout(&len, PTRIN(args->optlen), | ||||
sizeof(len)); | sizeof(len)); | ||||
out: | out: | ||||
free(sa, M_SONAME); | free(sa, M_SONAME); | ||||
} else { | } else { | ||||
bsd_args.val = PTRIN(args->optval); | if (args->optval) { | ||||
kib: != NULL | |||||
error = sys_getsockopt(td, &bsd_args); | error = copyin(PTRIN(args->optlen), &len, sizeof(len)); | ||||
if (error != 0) | |||||
return (error); | |||||
} | |||||
kibUnsubmitted Not Done Inline ActionsNo need for the empty line. kib: No need for the empty line. | |||||
error = kern_getsockopt(td, args->s, level, | |||||
name, PTRIN(args->optval), UIO_USERSPACE, &len); | |||||
kibUnsubmitted Not Done Inline ActionsSame. kib: Same. | |||||
if (error == 0) | |||||
error = copyout(&len, PTRIN(args->optlen), | |||||
sizeof(len)); | |||||
} | } | ||||
kibUnsubmitted Not Done Inline ActionsSame. kib: Same. | |||||
return (error); | return (error); | ||||
} | } | ||||
#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) | #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) | ||||
/* Argument list sizes for linux_socketcall */ | /* Argument list sizes for linux_socketcall */ | ||||
static const unsigned char lxs_args_cnt[] = { | static const unsigned char lxs_args_cnt[] = { | ||||
0 /* unused*/, 3 /* socket */, | 0 /* unused*/, 3 /* socket */, | ||||
▲ Show 20 Lines • Show All 84 Lines • Show Last 20 Lines |
!= NULL