aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-01-21 19:53:45 +0000
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-01-21 19:53:45 +0000
commit1e11762d5fabd80c70e226dd608fc6322de5ce61 (patch)
treee3229f494b5fe9b2aaef77a39905b84e202c70b4
parentdcebe56be139a0b4dbc4926c1d95e6dc4972ab67 (diff)
downloadlibmicrohttpd-1e11762d5fabd80c70e226dd608fc6322de5ce61.tar.gz
libmicrohttpd-1e11762d5fabd80c70e226dd608fc6322de5ce61.zip
Reworked code for using accept4(), epoll_create1() and socket() with SOCK_CLOEXEC, SOCK_NONBLOCK and EPOLL_CLOEXEC. On some systems SOCK_CLOEXEC, SOCK_NONBLOCK and EPOLL_CLOEXEC are defined as enum members with the same names so precompiler assume zero value of such macros.
-rw-r--r--ChangeLog8
-rw-r--r--src/microhttpd/daemon.c45
2 files changed, 31 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index dbb61e73..7b24960f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
1Thu Jan 21 19:35:18 CET 2016
2 Fixed old bug with making sockets non-blocking on
3 various platforms so now sockets are really
4 non-blocking on all supported platforms.
5 Reworked and fixed code for using SOCK_CLOEXEC,
6 SOCK_NONBLOCK and EPOLL_CLOEXEC resulting in
7 fewer used system calls. -EG
8
1Tue Jan 19 20:59:59 CET 2016 9Tue Jan 19 20:59:59 CET 2016
2 Cleaned up and optimized with minor fixes code for 10 Cleaned up and optimized with minor fixes code for
3 making sockets non-blocking non-inheritable. -EG 11 making sockets non-blocking non-inheritable. -EG
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index e313959e..1efcb43b 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -103,18 +103,26 @@
103#endif 103#endif
104#endif 104#endif
105 105
106#ifndef SOCK_CLOEXEC 106#ifdef SOCK_CLOEXEC
107#define SOCK_CLOEXEC 0 107#define MAYBE_SOCK_CLOEXEC SOCK_CLOEXEC
108#endif 108#else /* ! SOCK_CLOEXEC */
109#define MAYBE_SOCK_CLOEXEC 0
110#endif /* ! SOCK_CLOEXEC */
109 111
110#ifndef EPOLL_CLOEXEC 112#ifdef HAVE_SOCK_NONBLOCK
111#define EPOLL_CLOEXEC 0 113#define MAYBE_SOCK_NONBLOCK SOCK_NONBLOCK
112#endif 114#else /* ! HAVE_SOCK_NONBLOCK */
115#define MAYBE_SOCK_NONBLOCK 0
116#endif /* ! HAVE_SOCK_NONBLOCK */
113 117
114#if HAVE_ACCEPT4+0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || (SOCK_CLOEXEC+0 != 0)) 118#if HAVE_ACCEPT4+0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || defined(SOCK_CLOEXEC))
115#define USE_ACCEPT4 1 119#define USE_ACCEPT4 1
116#endif 120#endif
117 121
122#if defined(HAVE_EPOLL_CREATE1) && defined(EPOLL_CLOEXEC)
123#define USE_EPOLL_CREATE1 1
124#endif /* HAVE_EPOLL_CREATE1 && EPOLL_CLOEXEC */
125
118 126
119/** 127/**
120 * Default implementation of the panic function, 128 * Default implementation of the panic function,
@@ -1980,20 +1988,13 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1980 socklen_t addrlen; 1988 socklen_t addrlen;
1981 MHD_socket s; 1989 MHD_socket s;
1982 MHD_socket fd; 1990 MHD_socket fd;
1983#ifdef USE_ACCEPT4
1984#ifdef HAVE_SOCK_NONBLOCK
1985 static const int nonblock = SOCK_NONBLOCK;
1986#else
1987 static const int nonblock = 0;
1988#endif
1989#endif /* USE_ACCEPT4 */
1990 1991
1991 addrlen = sizeof (addrstorage); 1992 addrlen = sizeof (addrstorage);
1992 memset (addr, 0, sizeof (addrstorage)); 1993 memset (addr, 0, sizeof (addrstorage));
1993 if (MHD_INVALID_SOCKET == (fd = daemon->socket_fd)) 1994 if (MHD_INVALID_SOCKET == (fd = daemon->socket_fd))
1994 return MHD_NO; 1995 return MHD_NO;
1995#ifdef USE_ACCEPT4 1996#ifdef USE_ACCEPT4
1996 s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC | nonblock); 1997 s = accept4 (fd, addr, &addrlen, MAYBE_SOCK_CLOEXEC | MAYBE_SOCK_NONBLOCK);
1997#else /* ! USE_ACCEPT4 */ 1998#else /* ! USE_ACCEPT4 */
1998 s = accept (fd, addr, &addrlen); 1999 s = accept (fd, addr, &addrlen);
1999#endif /* ! USE_ACCEPT4 */ 2000#endif /* ! USE_ACCEPT4 */
@@ -2022,7 +2023,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
2022 make_nonblocking_noninheritable (daemon, s); 2023 make_nonblocking_noninheritable (daemon, s);
2023#elif !defined(HAVE_SOCK_NONBLOCK) 2024#elif !defined(HAVE_SOCK_NONBLOCK)
2024 make_nonblocking (daemon, s); 2025 make_nonblocking (daemon, s);
2025#elif SOCK_CLOEXEC+0 == 0 2026#elif !defined(SOCK_CLOEXEC)
2026 make_noninheritable (daemon, s); 2027 make_noninheritable (daemon, s);
2027#endif 2028#endif
2028#ifdef HAVE_MESSAGES 2029#ifdef HAVE_MESSAGES
@@ -3564,7 +3565,7 @@ create_listen_socket (struct MHD_Daemon *daemon,
3564 3565
3565 /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo 3566 /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
3566 * implementations do not set ai_socktype, e.g. RHL6.2. */ 3567 * implementations do not set ai_socktype, e.g. RHL6.2. */
3567#if defined(MHD_POSIX_SOCKETS) && SOCK_CLOEXEC+0 != 0 3568#if defined(MHD_POSIX_SOCKETS) && defined(SOCK_CLOEXEC)
3568 fd = socket (domain, type | SOCK_CLOEXEC, protocol); 3569 fd = socket (domain, type | SOCK_CLOEXEC, protocol);
3569 cloexec_set = MHD_YES; 3570 cloexec_set = MHD_YES;
3570#elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT) 3571#elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT)
@@ -3600,11 +3601,11 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
3600{ 3601{
3601 struct epoll_event event; 3602 struct epoll_event event;
3602 3603
3603#ifdef HAVE_EPOLL_CREATE1 3604#ifdef USE_EPOLL_CREATE1
3604 daemon->epoll_fd = epoll_create1 (EPOLL_CLOEXEC); 3605 daemon->epoll_fd = epoll_create1 (EPOLL_CLOEXEC);
3605#else /* !HAVE_EPOLL_CREATE1 */ 3606#else /* ! USE_EPOLL_CREATE1 */
3606 daemon->epoll_fd = epoll_create (MAX_EVENTS); 3607 daemon->epoll_fd = epoll_create (MAX_EVENTS);
3607#endif /* !HAVE_EPOLL_CREATE1 */ 3608#endif /* ! USE_EPOLL_CREATE1 */
3608 if (-1 == daemon->epoll_fd) 3609 if (-1 == daemon->epoll_fd)
3609 { 3610 {
3610#ifdef HAVE_MESSAGES 3611#ifdef HAVE_MESSAGES
@@ -3614,10 +3615,10 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
3614#endif 3615#endif
3615 return MHD_NO; 3616 return MHD_NO;
3616 } 3617 }
3617#if !defined(HAVE_EPOLL_CREATE1) || EPOLL_CLOEXEC+0 == 0 3618#if !defined(USE_EPOLL_CREATE1)
3618 make_noninheritable (daemon, 3619 make_noninheritable (daemon,
3619 daemon->epoll_fd); 3620 daemon->epoll_fd);
3620#endif /* !HAVE_EPOLL_CREATE1 || !EPOLL_CLOEXEC */ 3621#endif /* ! USE_EPOLL_CREATE1 */
3621 if (MHD_INVALID_SOCKET == daemon->socket_fd) 3622 if (MHD_INVALID_SOCKET == daemon->socket_fd)
3622 return MHD_YES; /* non-listening daemon */ 3623 return MHD_YES; /* non-listening daemon */
3623 event.events = EPOLLIN; 3624 event.events = EPOLLIN;