On Tue, Jun 19, 2012 at 02:02:03PM -0700, Philip Guenther wrote: > On Tue, Jun 19, 2012 at 1:26 AM, Paul Irofti <p...@irofti.net> wrote: > > The newer glibc's, when creating a socket, add some higher bit flags to > > the type argument that are used for debug, statistics, profiling > > whatever. They are not useful and implementation specific. > > Aren't those SOCK_CLOEXEC and SOCK_NONBLOCK? I would expect ignoring > the former to result in rapid fd leaks, and ignoring of the latter to > result in code blocking unexpectedly...
Thanks once again. How about this: Index: linux_socket.c =================================================================== RCS file: /cvs/src/sys/compat/linux/linux_socket.c,v retrieving revision 1.45 diff -u -p -r1.45 linux_socket.c --- linux_socket.c 19 Jun 2012 11:28:20 -0000 1.45 +++ linux_socket.c 20 Jun 2012 11:23:44 -0000 @@ -239,17 +239,50 @@ linux_socket(p, v, retval) } */ *uap = v; struct linux_socket_args lsa; struct sys_socket_args bsa; - int error; + struct sys_fcntl_args bfa; + struct sys_close_args bca; + int error, type_flags, fd; if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa))) return error; + type_flags = lsa.type & ~LINUX_SOCKET_TYPE_MASK; + if (type_flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK)) + return EINVAL; + SCARG(&bsa, protocol) = lsa.protocol; SCARG(&bsa, type) = lsa.type & LINUX_SOCKET_TYPE_MASK; SCARG(&bsa, domain) = linux_to_bsd_domain(lsa.domain); if (SCARG(&bsa, domain) == -1) return EINVAL; - return sys_socket(p, &bsa, retval); + error = sys_socket(p, &bsa, retval); + if (error) + return error; + + fd = SCARG(&bfa, fd) = retval[0]; + if (type_flags & LINUX_SOCK_NONBLOCK) { + SCARG(&bfa, cmd) = F_SETFL; + SCARG(&bfa, arg) = (void *)O_NONBLOCK; + error = sys_fcntl(p, &bfa, retval); + if (error) + goto err; + } + + if (type_flags & LINUX_SOCK_CLOEXEC) { + SCARG(&bfa, cmd) = F_SETFD; + SCARG(&bfa, arg) = (void *)FD_CLOEXEC; + error = sys_fcntl(p, &bfa, retval); + if (error) + goto err; + } + retval[0] = fd; + return error; + +err: + SCARG(&bca, fd) = fd; + sys_close(p, &bca, retval); + retval[0] = -1; + return error; } int Index: linux_socket.h =================================================================== RCS file: /cvs/src/sys/compat/linux/linux_socket.h,v retrieving revision 1.10 diff -u -p -r1.10 linux_socket.h --- linux_socket.h 19 Jun 2012 11:28:20 -0000 1.10 +++ linux_socket.h 20 Jun 2012 11:23:44 -0000 @@ -122,6 +122,8 @@ /* Mask out extra type-related options */ #define LINUX_SOCKET_TYPE_MASK 0xf +#define LINUX_SOCK_CLOEXEC 02000000 +#define LINUX_SOCK_NONBLOCK 00004000 struct linux_sockaddr { unsigned short sa_family;