diff options
author | Dmitry Chagin <dchagin@FreeBSD.org> | 2009-05-31 12:16:31 +0000 |
---|---|---|
committer | Dmitry Chagin <dchagin@FreeBSD.org> | 2009-05-31 12:16:31 +0000 |
commit | 39253cf9bb28d88bdd81d7c0a14a7322f25b5853 (patch) | |
tree | fffef19b8ea7021d84e1b562bc810902f154bf2b /sys/compat/linux | |
parent | 4202e1be20f290e17b1beddea8abd78703bb2d9a (diff) |
Implement a variation of the socketpair() syscall which takes a flags
in addition to the type argument.
Approved by: kib (mentor)
MFC after: 1 month
Notes
Notes:
svn path=/head/; revision=193168
Diffstat (limited to 'sys/compat/linux')
-rw-r--r-- | sys/compat/linux/linux_socket.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 3b7ce056361e..2dd4df80f24d 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -884,12 +884,20 @@ linux_socketpair(struct thread *td, struct linux_socketpair_args *args) int protocol; int *rsv; } */ bsd_args; + int error, socket_flags; + int sv[2]; bsd_args.domain = linux_to_bsd_domain(args->domain); if (bsd_args.domain != PF_LOCAL) return (EAFNOSUPPORT); - bsd_args.type = args->type; + socket_flags = args->type & ~LINUX_SOCK_TYPE_MASK; + if (socket_flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK)) + return (EINVAL); + bsd_args.type = args->type & LINUX_SOCK_TYPE_MASK; + if (bsd_args.type < 0 || bsd_args.type > LINUX_SOCK_MAX) + return (EINVAL); + if (args->protocol != 0 && args->protocol != PF_UNIX) /* @@ -902,7 +910,25 @@ linux_socketpair(struct thread *td, struct linux_socketpair_args *args) else bsd_args.protocol = 0; bsd_args.rsv = (int *)PTRIN(args->rsv); - return (socketpair(td, &bsd_args)); + error = kern_socketpair(td, bsd_args.domain, bsd_args.type, + bsd_args.protocol, sv); + if (error) + return (error); + error = linux_set_socket_flags(td, sv[0], socket_flags); + if (error) + goto out; + error = linux_set_socket_flags(td, sv[1], socket_flags); + if (error) + goto out; + + error = copyout(sv, bsd_args.rsv, 2 * sizeof(int)); + +out: + if (error) { + (void)kern_close(td, sv[0]); + (void)kern_close(td, sv[1]); + } + return (error); } struct linux_send_args { |