summaryrefslogtreecommitdiff
path: root/network_io/unix/sockets.c
diff options
context:
space:
mode:
authorBojan Smojver <bojan@apache.org>2009-06-12 03:21:22 +0000
committerBojan Smojver <bojan@apache.org>2009-06-12 03:21:22 +0000
commitd8c00503725305c6f41f6efd58c1a3dcc06d1fcd (patch)
tree77bb8b73a8798597440f7cb9bfc72c247fa9971f /network_io/unix/sockets.c
parentad67ed01e13eadec2f9531ec71dca8bf0ca82b9f (diff)
downloadapr-d8c00503725305c6f41f6efd58c1a3dcc06d1fcd.tar.gz
Backport r747990, r748361, r748371, r748565, r748988, r749810, r783958
from the trunk. Set CLOEXEC flags where appropriate. Either use new O_CLOEXEC flag and associated functions, such as dup3(), accept4(), epoll_create1() etc., or simply set CLOEXEC flag using fcntl(). Patch by Stefan Fritsch <sf sfritsch.de> and Arkadiusz Miskiewicz <arekm pld-linux.org>. PR 46425. fix unused variable warning for builds without HAVE_DUP3 Unroll APR_SET_FD_CLOEXEC macro. * One missing unroll of APR_SET_FD_CLOEXEC. Document CLOEXEC patch. Only set CLOEXEC on dup() if both NOCLEANUP and INHERIT flags are clear. Retain the INHERIT/NOCLEANUP flags of new_file in apr_file_dup2(). Patch by Stefan Fritsch <sf sfritsch.de>. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.4.x@783970 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'network_io/unix/sockets.c')
-rw-r--r--network_io/unix/sockets.c46
1 files changed, 40 insertions, 6 deletions
diff --git a/network_io/unix/sockets.c b/network_io/unix/sockets.c
index 94b26687c..a379b7bdd 100644
--- a/network_io/unix/sockets.c
+++ b/network_io/unix/sockets.c
@@ -83,7 +83,11 @@ apr_status_t apr_socket_protocol_get(apr_socket_t *sock, int *protocol)
apr_status_t apr_socket_create(apr_socket_t **new, int ofamily, int type,
int protocol, apr_pool_t *cont)
{
- int family = ofamily;
+ int family = ofamily, flags = 0;
+
+#ifdef HAVE_SOCK_CLOEXEC
+ flags |= SOCK_CLOEXEC;
+#endif
if (family == APR_UNSPEC) {
#if APR_HAVE_IPV6
@@ -96,19 +100,19 @@ apr_status_t apr_socket_create(apr_socket_t **new, int ofamily, int type,
alloc_socket(new, cont);
#ifndef BEOS_R5
- (*new)->socketdes = socket(family, type, protocol);
+ (*new)->socketdes = socket(family, type|flags, protocol);
#else
/* For some reason BeOS R5 has an unconventional protocol numbering,
* so we need to translate here. */
switch (protocol) {
case 0:
- (*new)->socketdes = socket(family, type, 0);
+ (*new)->socketdes = socket(family, type|flags, 0);
break;
case APR_PROTO_TCP:
- (*new)->socketdes = socket(family, type, IPPROTO_TCP);
+ (*new)->socketdes = socket(family, type|flags, IPPROTO_TCP);
break;
case APR_PROTO_UDP:
- (*new)->socketdes = socket(family, type, IPPROTO_UDP);
+ (*new)->socketdes = socket(family, type|flags, IPPROTO_UDP);
break;
case APR_PROTO_SCTP:
default:
@@ -121,7 +125,7 @@ apr_status_t apr_socket_create(apr_socket_t **new, int ofamily, int type,
#if APR_HAVE_IPV6
if ((*new)->socketdes < 0 && ofamily == APR_UNSPEC) {
family = APR_INET;
- (*new)->socketdes = socket(family, type, protocol);
+ (*new)->socketdes = socket(family, type|flags, protocol);
}
#endif
@@ -130,6 +134,19 @@ apr_status_t apr_socket_create(apr_socket_t **new, int ofamily, int type,
}
set_socket_vars(*new, family, type, protocol);
+#ifndef HAVE_SOCK_CLOEXEC
+ {
+ int flags;
+
+ if ((flags = fcntl((*new)->socketdes, F_GETFD)) == -1)
+ return errno;
+
+ flags |= FD_CLOEXEC;
+ if (fcntl((*new)->socketdes, F_SETFD, flags) == -1)
+ return errno;
+ }
+#endif
+
(*new)->timeout = -1;
(*new)->inherit = 0;
apr_pool_cleanup_register((*new)->pool, (void *)(*new), socket_cleanup,
@@ -181,7 +198,11 @@ apr_status_t apr_socket_accept(apr_socket_t **new, apr_socket_t *sock,
sa.salen = sizeof(sa.sa);
+#ifdef HAVE_ACCEPT4
+ s = accept4(sock->socketdes, (struct sockaddr *)&sa.sa, &sa.salen, SOCK_CLOEXEC);
+#else
s = accept(sock->socketdes, (struct sockaddr *)&sa.sa, &sa.salen);
+#endif
if (s < 0) {
return errno;
@@ -255,6 +276,19 @@ apr_status_t apr_socket_accept(apr_socket_t **new, apr_socket_t *sock,
(*new)->local_interface_unknown = 1;
}
+#ifndef HAVE_ACCEPT4
+ {
+ int flags;
+
+ if ((flags = fcntl((*new)->socketdes, F_GETFD)) == -1)
+ return errno;
+
+ flags |= FD_CLOEXEC;
+ if (fcntl((*new)->socketdes, F_SETFD, flags) == -1)
+ return errno;
+ }
+#endif
+
(*new)->inherit = 0;
apr_pool_cleanup_register((*new)->pool, (void *)(*new), socket_cleanup,
socket_cleanup);