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>
+
* posix.sgml: Mention dup3 and pipe2 as GNU extensions.
2010-01-14 Corinna Vinschen <corinna@vinschen.de>
abs NOSIGFE
_abs = abs NOSIGFE
accept = cygwin_accept SIGFE
+accept4 SIGFE
access SIGFE
_access = access SIGFE
acl SIGFE
int bind (const struct sockaddr *name, int namelen);
int connect (const struct sockaddr *name, int namelen);
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 getpeername (struct sockaddr *name, int *namelen);
int getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid);
/* 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.
}
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. */
struct sockaddr_storage lpeer;
sock->set_addr_family (get_addr_family ());
sock->set_socket_type (get_socket_type ());
sock->async_io (async_io ());
- sock->set_nonblocking (is_nonblocking ());
if (get_addr_family () == AF_LOCAL)
{
sock->set_sun_path (get_sun_path ());
}
}
}
+ 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. */
sock->wsock_events->events = wsock_events->events | FD_WRITE;
sock->wsock_events->owner = wsock_events->owner;
/* 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.
#define SOCK_RDM 4 /* reliably-delivered message */
#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. */
/*
* Address families.
/* version.h -- Cygwin version numbers and accompanying documentation.
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.
217: CW_GET_INSTKEY added.
218: Export get_nprocs, get_nprocs_conf, get_phys_pages, get_avphys_pages.
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 */
#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
shared memory regions. It is incremented when incompatible
/* 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.
#ifndef __INSIDE_CYGWIN_NET__
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 connect (int, const struct sockaddr *, socklen_t);
int getpeername (int, struct sockaddr *__peer, socklen_t *);
/* 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.
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);
{
((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;
}
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)
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);
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))
{
((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 ();
((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 ();
<sect1 id="std-gnu"><title>System interfaces compatible with GNU or Linux extensions:</title>
<screen>
+ accept4
argz_add
argz_add_sep
argz_append