* 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.
This commit is contained in:
Corinna Vinschen 2010-01-15 15:40:05 +00:00
parent 14c800a5ba
commit 0d6531551b
9 changed files with 102 additions and 12 deletions

View File

@ -1,3 +1,23 @@
2010-01-15 Corinna Vinschen <corinna@vinschen.de>
* 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.
2010-01-15 Corinna Vinschen <corinna@vinschen.de> 2010-01-15 Corinna Vinschen <corinna@vinschen.de>
* posix.sgml: Mention dup3 and pipe2 as GNU extensions. * posix.sgml: Mention dup3 and pipe2 as GNU extensions.

View File

@ -37,6 +37,7 @@ _abort = abort SIGFE
abs NOSIGFE abs NOSIGFE
_abs = abs NOSIGFE _abs = abs NOSIGFE
accept = cygwin_accept SIGFE accept = cygwin_accept SIGFE
accept4 SIGFE
access SIGFE access SIGFE
_access = access SIGFE _access = access SIGFE
acl SIGFE acl SIGFE

View File

@ -505,7 +505,7 @@ class fhandler_socket: public fhandler_base
int bind (const struct sockaddr *name, int namelen); int bind (const struct sockaddr *name, int namelen);
int connect (const struct sockaddr *name, int namelen); int connect (const struct sockaddr *name, int namelen);
int listen (int backlog); int listen (int backlog);
int accept (struct sockaddr *peer, int *len); int accept4 (struct sockaddr *peer, int *len, int flags);
int getsockname (struct sockaddr *name, int *namelen); int getsockname (struct sockaddr *name, int *namelen);
int getpeername (struct sockaddr *name, int *namelen); int getpeername (struct sockaddr *name, int *namelen);
int getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid); int getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid);

View File

@ -1,6 +1,7 @@
/* fhandler_socket.cc. See fhandler.h for a description of the fhandler classes. /* fhandler_socket.cc. See fhandler.h for a description of the fhandler classes.
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc. Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -1193,7 +1194,7 @@ fhandler_socket::listen (int backlog)
} }
int int
fhandler_socket::accept (struct sockaddr *peer, int *len) fhandler_socket::accept4 (struct sockaddr *peer, int *len, int flags)
{ {
/* Allows NULL peer and len parameters. */ /* Allows NULL peer and len parameters. */
struct sockaddr_storage lpeer; struct sockaddr_storage lpeer;
@ -1216,7 +1217,6 @@ fhandler_socket::accept (struct sockaddr *peer, int *len)
sock->set_addr_family (get_addr_family ()); sock->set_addr_family (get_addr_family ());
sock->set_socket_type (get_socket_type ()); sock->set_socket_type (get_socket_type ());
sock->async_io (async_io ()); sock->async_io (async_io ());
sock->set_nonblocking (is_nonblocking ());
if (get_addr_family () == AF_LOCAL) if (get_addr_family () == AF_LOCAL)
{ {
sock->set_sun_path (get_sun_path ()); sock->set_sun_path (get_sun_path ());
@ -1236,6 +1236,10 @@ fhandler_socket::accept (struct sockaddr *peer, int *len)
} }
} }
} }
sock->set_nonblocking (flags & SOCK_NONBLOCK
? true : is_nonblocking ());
if (flags & SOCK_CLOEXEC)
sock->set_close_on_exec (true);
/* No locking necessary at this point. */ /* No locking necessary at this point. */
sock->wsock_events->events = wsock_events->events | FD_WRITE; sock->wsock_events->events = wsock_events->events | FD_WRITE;
sock->wsock_events->owner = wsock_events->owner; sock->wsock_events->owner = wsock_events->owner;

View File

@ -1,6 +1,6 @@
/* cygwin/socket.h /* cygwin/socket.h
Copyright 1999, 2000, 2001, 2005, 2006, 2007, 2009 Red Hat, Inc. Copyright 1999, 2000, 2001, 2005, 2006, 2007, 2009, 2010 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -129,6 +129,14 @@ struct OLD_msghdr
#define SOCK_RDM 4 /* reliably-delivered message */ #define SOCK_RDM 4 /* reliably-delivered message */
#define SOCK_SEQPACKET 5 /* sequential packet socket */ #define SOCK_SEQPACKET 5 /* sequential packet socket */
/* GNU extension flags. Or them to the type parameter in calls to
socket(2) to mark socket as nonblocking and/or close-on-exec. */
#define SOCK_NONBLOCK 0x01000000
#define SOCK_CLOEXEC 0x02000000
#ifdef __INSIDE_CYGWIN__
#define _SOCK_FLAG_MASK 0xff000000 /* Bits left for more extensions */
#endif
/* Supported address families. */ /* Supported address families. */
/* /*
* Address families. * Address families.

View File

@ -1,7 +1,7 @@
/* version.h -- Cygwin version numbers and accompanying documentation. /* version.h -- Cygwin version numbers and accompanying documentation.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 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. This file is part of Cygwin.
@ -373,12 +373,13 @@ details. */
217: CW_GET_INSTKEY added. 217: CW_GET_INSTKEY added.
218: Export get_nprocs, get_nprocs_conf, get_phys_pages, get_avphys_pages. 218: Export get_nprocs, get_nprocs_conf, get_phys_pages, get_avphys_pages.
219: Export dup3, pipe2, O_CLOEXEC, F_DUPFD_CLOEXEC. 219: Export dup3, pipe2, O_CLOEXEC, F_DUPFD_CLOEXEC.
220: Export accept4, SOCK_CLOEXEC, SOCK_NONBLOCK.
*/ */
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0 #define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 219 #define CYGWIN_VERSION_API_MINOR 220
/* There is also a compatibity version number associated with the /* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible shared memory regions. It is incremented when incompatible

View File

@ -1,6 +1,7 @@
/* sys/socket.h /* sys/socket.h
Copyright 1996-2001 Red Hat, Inc. Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2005, 2006,
2009, 2010 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -27,6 +28,7 @@ extern "C"
#ifndef __INSIDE_CYGWIN_NET__ #ifndef __INSIDE_CYGWIN_NET__
int accept (int, struct sockaddr *__peer, socklen_t *); int accept (int, struct sockaddr *__peer, socklen_t *);
int accept4 (int, struct sockaddr *__peer, socklen_t *, int flags);
int bind (int, const struct sockaddr *__my_addr, socklen_t __addrlen); int bind (int, const struct sockaddr *__my_addr, socklen_t __addrlen);
int connect (int, const struct sockaddr *, socklen_t); int connect (int, const struct sockaddr *, socklen_t);
int getpeername (int, struct sockaddr *__peer, socklen_t *); int getpeername (int, struct sockaddr *__peer, socklen_t *);

View File

@ -1,7 +1,7 @@
/* net.cc: network-related routines. /* net.cc: network-related routines.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 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. This file is part of Cygwin.
@ -577,7 +577,16 @@ cygwin_socket (int af, int type, int protocol)
int res = -1; int res = -1;
SOCKET soc = 0; 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, soc = socket (af == AF_LOCAL ? AF_INET : af, type,
af == AF_LOCAL ? 0 : protocol); 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_addr_family (af);
((fhandler_socket *) fd)->set_socket_type (type); ((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; res = fd;
} }
} }
done: 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; return res;
} }
@ -1242,12 +1256,35 @@ cygwin_accept (int fd, struct sockaddr *peer, socklen_t *len)
if (efault.faulted (EFAULT) || !fh) if (efault.faulted (EFAULT) || !fh)
res = -1; res = -1;
else else
res = fh->accept (peer, len); res = fh->accept4 (peer, len, 0);
syscall_printf ("%d = accept (%d, %p, %p)", res, fd, peer, len); syscall_printf ("%d = accept (%d, %p, %p)", res, fd, peer, len);
return res; 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? */ /* exported as bind: standards? */
extern "C" int extern "C" int
cygwin_bind (int fd, const struct sockaddr *my_addr, socklen_t addrlen) 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)) if (efault.faulted (EFAULT))
return -1; return -1;
int flags = type & _SOCK_FLAG_MASK;
type &= ~_SOCK_FLAG_MASK;
if (family != AF_LOCAL && family != AF_INET) if (family != AF_LOCAL && family != AF_INET)
{ {
set_errno (EAFNOSUPPORT); set_errno (EAFNOSUPPORT);
@ -2787,6 +2827,11 @@ socketpair (int family, int type, int protocol, int *sb)
set_errno (EPROTOTYPE); set_errno (EPROTOTYPE);
goto done; goto done;
} }
if ((flags & ~(SOCK_NONBLOCK | SOCK_CLOEXEC)) != 0)
{
set_errno (EINVAL);
goto done;
}
if ((family == AF_LOCAL && protocol != PF_UNSPEC && protocol != PF_LOCAL) if ((family == AF_LOCAL && protocol != PF_UNSPEC && protocol != PF_LOCAL)
|| (family == AF_INET && protocol != PF_UNSPEC && protocol != PF_INET)) || (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_addr_family (family);
((fhandler_socket *) sb0)->set_socket_type (type); ((fhandler_socket *) sb0)->set_socket_type (type);
((fhandler_socket *) sb0)->connect_state (connected); ((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) if (family == AF_LOCAL && type == SOCK_STREAM)
((fhandler_socket *) sb0)->af_local_set_sockpair_cred (); ((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_addr_family (family);
((fhandler_socket *) sb1)->set_socket_type (type); ((fhandler_socket *) sb1)->set_socket_type (type);
((fhandler_socket *) sb1)->connect_state (connected); ((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) if (family == AF_LOCAL && type == SOCK_STREAM)
((fhandler_socket *) sb1)->af_local_set_sockpair_cred (); ((fhandler_socket *) sb1)->af_local_set_sockpair_cred ();

View File

@ -992,6 +992,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
<sect1 id="std-gnu"><title>System interfaces compatible with GNU or Linux extensions:</title> <sect1 id="std-gnu"><title>System interfaces compatible with GNU or Linux extensions:</title>
<screen> <screen>
accept4
argz_add argz_add
argz_add_sep argz_add_sep
argz_append argz_append