diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2010-01-15 18:40:05 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2010-01-15 18:40:05 +0300 |
commit | 0d6531551b6bf4037017c97d7f7ece5b83739601 (patch) | |
tree | 7fa8946d313748126bbe721da0b66f51e6094493 /winsup/cygwin/net.cc | |
parent | 14c800a5ba66195a80dfc02ffb0ea7da5f737bd7 (diff) |
* cygwin.din (accept4): Export.
* fhandler.h (fhandler_socket::accept4): Rename from accept. Take
additional flag parameter.
* fhandler_socket.cc (fhandler_socket::accept4): Ditto. Handle
SOCK_NONBLOCK and SOCK_CLOEXEC flags.
* net.cc (cygwin_socket): Handle SOCK_NONBLOCK and SOCK_CLOEXEC flags
in type. Check for invalid flag values.
(socketpair): Ditto.
(cygwin_accept): Accommodate renaming of fhandler_socket::accept
function to accept4.
(accept4): New function.
* posix.sgml: Mention accept4 as GNU extensions.
* include/cygwin/socket.h (SOCK_NONBLOCK): Define.
(SOCK_CLOEXEC): Define.
(_SOCK_FLAG_MASK): Define when building Cygwin.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
* include/sys/socket.h (accept4): Declare.
Diffstat (limited to 'winsup/cygwin/net.cc')
-rw-r--r-- | winsup/cygwin/net.cc | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index a7f913ac5..93d39d9e5 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -1,7 +1,7 @@ /* net.cc: network-related routines. Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009 Red Hat, Inc. + 2005, 2006, 2007, 2008, 2009, 2010 Red Hat, Inc. This file is part of Cygwin. @@ -577,7 +577,16 @@ cygwin_socket (int af, int type, int protocol) int res = -1; SOCKET soc = 0; - debug_printf ("socket (%d, %d, %d)", af, type, protocol); + int flags = type & _SOCK_FLAG_MASK; + type &= ~_SOCK_FLAG_MASK; + + debug_printf ("socket (%d, %d (flags %p), %d)", af, type, flags, protocol); + + if ((flags & ~(SOCK_NONBLOCK | SOCK_CLOEXEC)) != 0) + { + set_errno (EINVAL); + goto done; + } soc = socket (af == AF_LOCAL ? AF_INET : af, type, af == AF_LOCAL ? 0 : protocol); @@ -603,12 +612,17 @@ cygwin_socket (int af, int type, int protocol) { ((fhandler_socket *) fd)->set_addr_family (af); ((fhandler_socket *) fd)->set_socket_type (type); + if (flags & SOCK_NONBLOCK) + ((fhandler_socket *) fd)->set_nonblocking (true); + if (flags & SOCK_CLOEXEC) + ((fhandler_socket *) fd)->set_close_on_exec (true); res = fd; } } done: - syscall_printf ("%d = socket (%d, %d, %d)", res, af, type, protocol); + syscall_printf ("%d = socket (%d, %d (flags %p), %d)", + res, af, type, flags, protocol); return res; } @@ -1242,12 +1256,35 @@ cygwin_accept (int fd, struct sockaddr *peer, socklen_t *len) if (efault.faulted (EFAULT) || !fh) res = -1; else - res = fh->accept (peer, len); + res = fh->accept4 (peer, len, 0); syscall_printf ("%d = accept (%d, %p, %p)", res, fd, peer, len); return res; } +extern "C" int +accept4 (int fd, struct sockaddr *peer, socklen_t *len, int flags) +{ + int res; + sig_dispatch_pending (); + + fhandler_socket *fh = get (fd); + + myfault efault; + if (efault.faulted (EFAULT) || !fh) + res = -1; + else if ((flags & ~(SOCK_NONBLOCK | SOCK_CLOEXEC)) != 0) + { + set_errno (EINVAL); + res = -1; + } + else + res = fh->accept4 (peer, len, flags); + + syscall_printf ("%d = accept4 (%d, %p, %p, %p)", res, fd, peer, len, flags); + return res; +} + /* exported as bind: standards? */ extern "C" int cygwin_bind (int fd, const struct sockaddr *my_addr, socklen_t addrlen) @@ -2777,6 +2814,9 @@ socketpair (int family, int type, int protocol, int *sb) if (efault.faulted (EFAULT)) return -1; + int flags = type & _SOCK_FLAG_MASK; + type &= ~_SOCK_FLAG_MASK; + if (family != AF_LOCAL && family != AF_INET) { set_errno (EAFNOSUPPORT); @@ -2787,6 +2827,11 @@ socketpair (int family, int type, int protocol, int *sb) set_errno (EPROTOTYPE); goto done; } + if ((flags & ~(SOCK_NONBLOCK | SOCK_CLOEXEC)) != 0) + { + set_errno (EINVAL); + goto done; + } if ((family == AF_LOCAL && protocol != PF_UNSPEC && protocol != PF_LOCAL) || (family == AF_INET && protocol != PF_UNSPEC && protocol != PF_INET)) { @@ -2921,6 +2966,10 @@ socketpair (int family, int type, int protocol, int *sb) ((fhandler_socket *) sb0)->set_addr_family (family); ((fhandler_socket *) sb0)->set_socket_type (type); ((fhandler_socket *) sb0)->connect_state (connected); + if (flags & SOCK_NONBLOCK) + ((fhandler_socket *) sb0)->set_nonblocking (true); + if (flags & SOCK_CLOEXEC) + ((fhandler_socket *) sb0)->set_close_on_exec (true); if (family == AF_LOCAL && type == SOCK_STREAM) ((fhandler_socket *) sb0)->af_local_set_sockpair_cred (); @@ -2931,6 +2980,10 @@ socketpair (int family, int type, int protocol, int *sb) ((fhandler_socket *) sb1)->set_addr_family (family); ((fhandler_socket *) sb1)->set_socket_type (type); ((fhandler_socket *) sb1)->connect_state (connected); + if (flags & SOCK_NONBLOCK) + ((fhandler_socket *) sb1)->set_nonblocking (true); + if (flags & SOCK_CLOEXEC) + ((fhandler_socket *) sb1)->set_close_on_exec (true); if (family == AF_LOCAL && type == SOCK_STREAM) ((fhandler_socket *) sb1)->af_local_set_sockpair_cred (); |