libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit f143bdcad91a1141ea6f7f771021724e38691fee
parent 4cf082ba053867a7f9749f785627a1a80b2743a0
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Tue, 23 Aug 2016 20:13:32 +0000

Moved create_listen_socket() to mhd_sockets.c, better error handling and checking on Darwin.

Diffstat:
Msrc/microhttpd/daemon.c | 55++-----------------------------------------------------
Msrc/microhttpd/mhd_sockets.c | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/microhttpd/mhd_sockets.h | 10++++++++++
3 files changed, 68 insertions(+), 53 deletions(-)

diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c @@ -3414,52 +3414,6 @@ parse_options_va (struct MHD_Daemon *daemon, } -/** - * Create a listen socket, if possible with SOCK_CLOEXEC flag set. - * - * @param daemon daemon for which we create the socket - * @param domain socket domain (i.e. PF_INET) - * @param type socket type (usually SOCK_STREAM) - * @param protocol desired protocol, 0 for default - */ -static MHD_socket -create_listen_socket (struct MHD_Daemon *daemon, - int domain, int type, int protocol) -{ - MHD_socket fd; - int cloexec_set; -#if defined(OSX) && defined(SOL_SOCKET) && defined(SO_NOSIGPIPE) - static const int on_val = 1; -#endif - - /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo - * implementations do not set ai_socktype, e.g. RHL6.2. */ -#if defined(MHD_POSIX_SOCKETS) && defined(SOCK_CLOEXEC) - fd = socket (domain, type | SOCK_CLOEXEC, protocol); - cloexec_set = MHD_YES; -#elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT) - fd = WSASocketW (domain, type, protocol, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT); - cloexec_set = MHD_YES; -#else /* !SOCK_CLOEXEC */ - fd = socket (domain, type, protocol); - cloexec_set = MHD_NO; -#endif /* !SOCK_CLOEXEC */ - if ( (MHD_INVALID_SOCKET == fd) && (MHD_NO != cloexec_set) ) - { - fd = socket (domain, type, protocol); - cloexec_set = MHD_NO; - } - if (MHD_INVALID_SOCKET == fd) - return MHD_INVALID_SOCKET; -#if defined(OSX) && defined(SOL_SOCKET) && defined(SO_NOSIGPIPE) - setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &on_val, sizeof(on_val)); -#endif - if (MHD_NO == cloexec_set) - MHD_socket_noninheritable_ (fd); - return fd; -} - - #if EPOLL_SUPPORT /** * Setup epoll() FD for the daemon and initialize it to listen @@ -3797,17 +3751,12 @@ MHD_start_daemon_va (unsigned int flags, (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) ) { /* try to open listen socket */ - if (0 != (flags & MHD_USE_IPv6)) - socket_fd = create_listen_socket (daemon, - PF_INET6, SOCK_STREAM, 0); - else - socket_fd = create_listen_socket (daemon, - PF_INET, SOCK_STREAM, 0); + socket_fd = MHD_socket_create_listen_(flags & MHD_USE_IPv6); if (MHD_INVALID_SOCKET == socket_fd) { #ifdef HAVE_MESSAGES MHD_DLOG (daemon, - "Call to socket failed: %s\n", + "Failed to create socket for listening: %s\n", MHD_socket_last_strerr_ ()); #endif goto free_and_fail; diff --git a/src/microhttpd/mhd_sockets.c b/src/microhttpd/mhd_sockets.c @@ -325,3 +325,59 @@ MHD_socket_noninheritable_ (MHD_socket sock) #endif /* MHD_WINSOCK_SOCKETS */ return !0; } + + +/** + * Create a listen socket, with noninheritable flag if possible. + * + * @param use_ipv6 if set to non-zero IPv6 is used + * @return created socket or MHD_INVALID_SOCKET in case of errors + */ +MHD_socket +MHD_socket_create_listen_ (int use_ipv6) +{ + int domain; + MHD_socket fd; + int cloexec_set; +#if defined(OSX) && defined(SOL_SOCKET) && defined(SO_NOSIGPIPE) + static const int on_val = 1; +#endif + +#ifdef HAVE_INET6 + domain = (use_ipv6) ? PF_INET6 : PF_INET; +#else /* ! HAVE_INET6 */ + if (use_ipv6) + return MHD_INVALID_SOCKET; + domain = PF_INET; +#endif /* ! HAVE_INET6 */ + +#if defined(MHD_POSIX_SOCKETS) && defined(SOCK_CLOEXEC) + fd = socket (domain, SOCK_STREAM | SOCK_CLOEXEC, 0); + cloexec_set = !0; +#elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT) + fd = WSASocketW (domain, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT); + cloexec_set = !0; +#else /* !SOCK_CLOEXEC */ + fd = MHD_INVALID_SOCKET; +#endif /* !SOCK_CLOEXEC */ + if (MHD_INVALID_SOCKET == fd) + { + fd = socket (domain, SOCK_STREAM, 0); + cloexec_set = 0; + } + if (MHD_INVALID_SOCKET == fd) + return MHD_INVALID_SOCKET; +#if defined(OSX) && defined(SOL_SOCKET) && defined(SO_NOSIGPIPE) + if(0 != setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &on_val, sizeof(on_val))) + { + int err = MHD_socket_get_error_(); + MHD_socket_close_(fd); + MHD_socket_fset_error_(err); + return MHD_INVALID_SOCKET; + } +#endif + if (!cloexec_set) + (void)MHD_socket_noninheritable_(fd); + + return fd; +} diff --git a/src/microhttpd/mhd_sockets.h b/src/microhttpd/mhd_sockets.h @@ -608,4 +608,14 @@ MHD_socket_nonblocking_ (MHD_socket sock); int MHD_socket_noninheritable_ (MHD_socket sock); + +/** + * Create a listen socket, with noninheritable flag if possible. + * + * @param use_ipv6 if set to non-zero IPv6 is used + * @return created socket or MHD_INVALID_SOCKET in case of errors + */ +MHD_socket +MHD_socket_create_listen_ (int use_ipv6); + #endif /* ! MHD_SOCKETS_H */