Changeset View
Changeset View
Standalone View
Standalone View
head/sys/compat/linux/linux_socket.c
Show All 34 Lines | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/sysproto.h> | #include <sys/sysproto.h> | ||||
#include <sys/capsicum.h> | #include <sys/capsicum.h> | ||||
#include <sys/fcntl.h> | #include <sys/fcntl.h> | ||||
#include <sys/file.h> | #include <sys/file.h> | ||||
#include <sys/filedesc.h> | |||||
#include <sys/limits.h> | #include <sys/limits.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/mbuf.h> | #include <sys/mbuf.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/socketvar.h> | #include <sys/socketvar.h> | ||||
#include <sys/syscallsubr.h> | #include <sys/syscallsubr.h> | ||||
▲ Show 20 Lines • Show All 555 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static int | static int | ||||
linux_accept_common(struct thread *td, int s, l_uintptr_t addr, | linux_accept_common(struct thread *td, int s, l_uintptr_t addr, | ||||
l_uintptr_t namelen, int flags) | l_uintptr_t namelen, int flags) | ||||
{ | { | ||||
struct l_sockaddr *lsa; | struct l_sockaddr *lsa; | ||||
struct sockaddr *sa; | struct sockaddr *sa; | ||||
struct file *fp; | struct file *fp, *fp1; | ||||
int bflags, len; | int bflags, len; | ||||
struct socket *so; | struct socket *so; | ||||
int error, error1; | int error, error1; | ||||
bflags = 0; | bflags = 0; | ||||
fp = NULL; | |||||
sa = NULL; | |||||
error = linux_set_socket_flags(flags, &bflags); | error = linux_set_socket_flags(flags, &bflags); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
sa = NULL; | |||||
if (PTRIN(addr) == NULL) { | if (PTRIN(addr) == NULL) { | ||||
len = 0; | len = 0; | ||||
error = kern_accept4(td, s, NULL, NULL, bflags, NULL); | error = kern_accept4(td, s, NULL, NULL, bflags, NULL); | ||||
} else { | } else { | ||||
error = copyin(PTRIN(namelen), &len, sizeof(len)); | error = copyin(PTRIN(namelen), &len, sizeof(len)); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
if (len < 0) | if (len < 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
error = kern_accept4(td, s, &sa, &len, bflags, &fp); | error = kern_accept4(td, s, &sa, &len, bflags, &fp); | ||||
if (error == 0) | |||||
fdrop(fp, td); | |||||
} | } | ||||
/* | |||||
* Translate errno values into ones used by Linux. | |||||
*/ | |||||
if (error != 0) { | if (error != 0) { | ||||
/* | /* | ||||
* XXX. This is wrong, different sockaddr structures | * XXX. This is wrong, different sockaddr structures | ||||
* have different sizes. | * have different sizes. | ||||
*/ | */ | ||||
if (error == EFAULT && namelen != sizeof(struct sockaddr_in)) | switch (error) { | ||||
{ | case EFAULT: | ||||
if (namelen != sizeof(struct sockaddr_in)) | |||||
error = EINVAL; | error = EINVAL; | ||||
goto out; | break; | ||||
} | case EINVAL: | ||||
if (error == EINVAL) { | error1 = getsock_cap(td, s, &cap_accept_rights, &fp1, NULL, NULL); | ||||
error1 = getsock_cap(td, s, &cap_accept_rights, &fp, NULL, NULL); | |||||
if (error1 != 0) { | if (error1 != 0) { | ||||
error = error1; | error = error1; | ||||
goto out; | break; | ||||
} | } | ||||
so = fp->f_data; | so = fp1->f_data; | ||||
if (so->so_type == SOCK_DGRAM) | if (so->so_type == SOCK_DGRAM) | ||||
error = EOPNOTSUPP; | error = EOPNOTSUPP; | ||||
fdrop(fp, td); | fdrop(fp1, td); | ||||
break; | |||||
} | } | ||||
goto out; | return (error); | ||||
} | } | ||||
if (len != 0 && error == 0) { | if (len != 0) { | ||||
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(addr), len); | error = copyout(lsa, PTRIN(addr), len); | ||||
free(lsa, M_SONAME); | free(lsa, M_SONAME); | ||||
} | |||||
free(sa, M_SONAME); | /* | ||||
* XXX: We should also copyout the len, shouldn't we? | |||||
*/ | |||||
out: | |||||
if (error != 0) { | if (error != 0) { | ||||
(void)kern_close(td, td->td_retval[0]); | fdclose(td, fp, td->td_retval[0]); | ||||
td->td_retval[0] = 0; | td->td_retval[0] = 0; | ||||
} | } | ||||
} | |||||
if (fp != NULL) | |||||
fdrop(fp, td); | |||||
free(sa, M_SONAME); | |||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
linux_accept(struct thread *td, struct linux_accept_args *args) | linux_accept(struct thread *td, struct linux_accept_args *args) | ||||
{ | { | ||||
return (linux_accept_common(td, args->s, args->addr, | return (linux_accept_common(td, args->s, args->addr, | ||||
▲ Show 20 Lines • Show All 1,139 Lines • Show Last 20 Lines |