summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authordchagin <dchagin@FreeBSD.org>2009-05-31 12:16:31 +0000
committerdchagin <dchagin@FreeBSD.org>2009-05-31 12:16:31 +0000
commit6fb0275352a53e468de58a1124fc5b35e9234143 (patch)
treefffef19b8ea7021d84e1b562bc810902f154bf2b /sys/compat
parentceed8fedd1150a6a8402e15ed264f72c76fb2a6a (diff)
downloadFreeBSD-src-6fb0275352a53e468de58a1124fc5b35e9234143.zip
FreeBSD-src-6fb0275352a53e468de58a1124fc5b35e9234143.tar.gz
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
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/linux/linux_socket.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index 3b7ce05..2dd4df8 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 {
OpenPOWER on IntegriCloud