aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-08-27 16:43:53 +0000
committerChristian Grothoff <christian@grothoff.org>2013-08-27 16:43:53 +0000
commita23e55f20b487f063c7639c2068ac733895c7c0e (patch)
tree36de612ac058597c112fde327b11494d7c4fede5
parent3d605e4ad199b7329358df81a22eb6dbac0c77fa (diff)
downloadlibmicrohttpd-a23e55f20b487f063c7639c2068ac733895c7c0e.tar.gz
libmicrohttpd-a23e55f20b487f063c7639c2068ac733895c7c0e.zip
making build tolerate missing SOCK_NONBLOCK/EPOLL_CLOEXEC (older glibc)
-rw-r--r--ChangeLog4
-rw-r--r--src/microhttpd/daemon.c66
2 files changed, 25 insertions, 45 deletions
diff --git a/ChangeLog b/ChangeLog
index a94caa00..252c09ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
1Tue Aug 27 18:39:08 CEST 2013
2 Fix build issue if SOCK_NONBLOCK/EPOLL_CLOEXEC are not
3 defined (as is the case on older glibc versions). -CG
4
1Mon Aug 12 23:51:18 CEST 2013 5Mon Aug 12 23:51:18 CEST 2013
2 Updated manual, documenting W32 select/shutdown issue. -CG 6 Updated manual, documenting W32 select/shutdown issue. -CG
3 7
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 7f366966..563c5bb4 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -86,6 +86,10 @@
86#define SOCK_CLOEXEC 0 86#define SOCK_CLOEXEC 0
87#endif 87#endif
88 88
89#ifndef EPOLL_CLOEXEC
90#define EPOLL_CLOEXEC 0
91#endif
92
89 93
90/** 94/**
91 * Default implementation of the panic function, 95 * Default implementation of the panic function,
@@ -1511,9 +1515,8 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1511 } 1515 }
1512 return MHD_NO; 1516 return MHD_NO;
1513 } 1517 }
1514#if !HAVE_ACCEPT4 1518 if ( (! HAVE_ACCEPT4) || (0 == SOCK_CLOEXEC) )
1515 make_nonblocking_noninheritable (daemon, s); 1519 make_nonblocking_noninheritable (daemon, s);
1516#endif
1517#if HAVE_MESSAGES 1520#if HAVE_MESSAGES
1518#if DEBUG_CONNECT 1521#if DEBUG_CONNECT
1519 MHD_DLOG (daemon, "Accepted connection on socket %d\n", s); 1522 MHD_DLOG (daemon, "Accepted connection on socket %d\n", s);
@@ -2794,62 +2797,30 @@ parse_options_va (struct MHD_Daemon *daemon,
2794/** 2797/**
2795 * Create a listen socket, if possible with CLOEXEC flag set. 2798 * Create a listen socket, if possible with CLOEXEC flag set.
2796 * 2799 *
2800 * @param daemon daemon for which we create the socket
2797 * @param domain socket domain (i.e. PF_INET) 2801 * @param domain socket domain (i.e. PF_INET)
2798 * @param type socket type (usually SOCK_STREAM) 2802 * @param type socket type (usually SOCK_STREAM)
2799 * @param protocol desired protocol, 0 for default 2803 * @param protocol desired protocol, 0 for default
2800 */ 2804 */
2801static int 2805static int
2802create_socket (int domain, int type, int protocol) 2806create_socket (struct MHD_Daemon *daemon,
2807 int domain, int type, int protocol)
2803{ 2808{
2804 static int sock_cloexec = SOCK_CLOEXEC; 2809 int ctype = type | SOCK_CLOEXEC;
2805 int ctype = SOCK_STREAM | sock_cloexec;
2806 int fd; 2810 int fd;
2807 int flags;
2808#ifdef WINDOWS
2809 DWORD dwFlags;
2810#endif
2811 2811
2812 /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo 2812 /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
2813 * implementations do not set ai_socktype, e.g. RHL6.2. */ 2813 * implementations do not set ai_socktype, e.g. RHL6.2. */
2814 fd = SOCKET (domain, ctype, protocol); 2814 fd = SOCKET (domain, ctype, protocol);
2815 if ( (-1 == fd) && (EINVAL == errno) && (0 != sock_cloexec) ) 2815 if ( (-1 == fd) && (EINVAL == errno) && (0 != SOCK_CLOEXEC) )
2816 { 2816 {
2817 sock_cloexec = 0; 2817 ctype = type;
2818 fd = SOCKET(domain, type, protocol); 2818 fd = SOCKET(domain, type, protocol);
2819 } 2819 }
2820 if (-1 == fd) 2820 if (-1 == fd)
2821 return -1; 2821 return -1;
2822 if (0 != sock_cloexec) 2822 if (type == ctype)
2823 return fd; /* this is it */ 2823 make_nonblocking_noninheritable (daemon, fd);
2824 /* flag was not set during 'socket' call, let's try setting it manually */
2825#ifndef WINDOWS
2826 flags = fcntl (fd, F_GETFD);
2827 if (flags < 0)
2828#else
2829 if (!GetHandleInformation ((HANDLE) fd, &dwFlags))
2830#endif
2831 {
2832#ifdef WINDOWS
2833 SetErrnoFromWinError (GetLastError ());
2834#endif
2835 return fd; /* good luck */
2836 }
2837#ifndef WINDOWS
2838 if (flags == (flags | FD_CLOEXEC))
2839 return fd; /* already set */
2840 flags |= FD_CLOEXEC;
2841 if (0 != fcntl (fd, F_SETFD, flags))
2842#else
2843 if (dwFlags != (dwFlags | HANDLE_FLAG_INHERIT))
2844 return fd; /* already unset */
2845 if (!SetHandleInformation ((HANDLE) fd, HANDLE_FLAG_INHERIT, 0))
2846#endif
2847 {
2848#ifdef WINDOWS
2849 SetErrnoFromWinError (GetLastError ());
2850#endif
2851 return fd; /* good luck */
2852 }
2853 return fd; 2824 return fd;
2854} 2825}
2855 2826
@@ -2878,6 +2849,9 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
2878#endif 2849#endif
2879 return MHD_NO; 2850 return MHD_NO;
2880 } 2851 }
2852 if (0 == EPOLL_CLOEXEC)
2853 make_nonblocking_noninheritable (daemon,
2854 daemon->epoll_fd);
2881 if (-1 == daemon->socket_fd) 2855 if (-1 == daemon->socket_fd)
2882 return MHD_YES; /* non-listening daemon */ 2856 return MHD_YES; /* non-listening daemon */
2883 event.events = EPOLLIN; 2857 event.events = EPOLLIN;
@@ -3155,9 +3129,11 @@ MHD_start_daemon_va (unsigned int flags,
3155 { 3129 {
3156 /* try to open listen socket */ 3130 /* try to open listen socket */
3157 if ((flags & MHD_USE_IPv6) != 0) 3131 if ((flags & MHD_USE_IPv6) != 0)
3158 socket_fd = create_socket (PF_INET6, SOCK_STREAM, 0); 3132 socket_fd = create_socket (daemon,
3133 PF_INET6, SOCK_STREAM, 0);
3159 else 3134 else
3160 socket_fd = create_socket (PF_INET, SOCK_STREAM, 0); 3135 socket_fd = create_socket (daemon,
3136 PF_INET, SOCK_STREAM, 0);
3161 if (-1 == socket_fd) 3137 if (-1 == socket_fd)
3162 { 3138 {
3163#if HAVE_MESSAGES 3139#if HAVE_MESSAGES