package: haproxy
authorThomas Heil <heil@terminal-consulting.de>
Tue, 2 Apr 2013 13:52:02 +0000 (13:52 +0000)
committerThomas Heil <heil@terminal-consulting.de>
Tue, 2 Apr 2013 13:52:02 +0000 (13:52 +0000)
 - add backported patches for 1.4.22

SVN-Revision: 36152

net/haproxy/Makefile
net/haproxy/patches/0036-MEDIUM-http-implement-redirect-307-and-308.patch [new file with mode: 0644]
net/haproxy/patches/0037-MINOR-http-status-301-should-not-be-marked-non-cache.patch [new file with mode: 0644]
net/haproxy/patches/0038-DOC-mention-the-new-HTTP-307-and-308-redirect-statue.patch [new file with mode: 0644]
net/haproxy/patches/0039-MEDIUM-poll-do-not-use-FD_-macros-anymore.patch [new file with mode: 0644]
net/haproxy/patches/0040-BUG-MAJOR-ev_select-disable-the-select-poller-if-max.patch [new file with mode: 0644]
net/haproxy/patches/0041-BUILD-enable-poll-by-default-in-the-makefile.patch [new file with mode: 0644]
net/haproxy/patches/0042-BUILD-add-explicit-support-for-Mac-OS-X.patch [new file with mode: 0644]

index bd3bc9e50ad02957a0ffb99c4ae6ae20f7815f43..ff4028981ef7557e6d0429b15ebd0d0a129b144f 100644 (file)
@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=haproxy
 PKG_VERSION:=1.4.22
-PKG_RELEASE:=35
+PKG_RELEASE:=42
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.4/src
diff --git a/net/haproxy/patches/0036-MEDIUM-http-implement-redirect-307-and-308.patch b/net/haproxy/patches/0036-MEDIUM-http-implement-redirect-307-and-308.patch
new file mode 100644 (file)
index 0000000..56554ba
--- /dev/null
@@ -0,0 +1,71 @@
+From 8a92e409e706e503ba76f8863c87409192e9f082 Mon Sep 17 00:00:00 2001
+From: Yves Lafon <ylafon@w3.org>
+Date: Mon, 11 Mar 2013 11:06:05 -0400
+Subject: [PATCH 36/42] MEDIUM: http: implement redirect 307 and 308
+
+I needed to emit a 307 and noticed it was not available so I did it,
+as well as 308.
+(cherry picked from commit 3e8d1ae2d25d3fae659fc560506af2ae9b20da12)
+---
+ src/cfgparse.c   |  6 +++---
+ src/proto_http.c | 20 ++++++++++++++++++++
+ 2 files changed, 23 insertions(+), 3 deletions(-)
+
+diff --git a/src/cfgparse.c b/src/cfgparse.c
+index e55d30a..345b415 100644
+--- a/src/cfgparse.c
++++ b/src/cfgparse.c
+@@ -2215,9 +2215,9 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
+                               }
+                               cur_arg++;
+                               code = atol(args[cur_arg]);
+-                              if (code < 301 || code > 303) {
+-                                      Alert("parsing [%s:%d] : '%s': unsupported HTTP code '%d'.\n",
+-                                            file, linenum, args[0], code);
++                              if (code < 301 || code > 308 || (code > 303 && code < 307)) {
++                                      Alert("parsing [%s:%d] : '%s': unsupported HTTP code '%s' (must be one of 301, 302, 303, 307 or 308).\n",
++                                            file, linenum, args[0], args[cur_arg]);
+                                       err_code |= ERR_ALERT | ERR_FATAL;
+                                       goto out;
+                               }
+diff --git a/src/proto_http.c b/src/proto_http.c
+index 06b3743..8d9d8e8 100644
+--- a/src/proto_http.c
++++ b/src/proto_http.c
+@@ -90,6 +90,20 @@ const char *HTTP_303 =
+       "Content-length: 0\r\n"
+       "Location: "; /* not terminated since it will be concatenated with the URL */
++
++/* same as 302 except that the browser MUST retry with the same method */
++const char *HTTP_307 =
++      "HTTP/1.1 307 Temporary Redirect\r\n"
++      "Cache-Control: no-cache\r\n"
++      "Content-length: 0\r\n"
++      "Location: "; /* not terminated since it will be concatenated with the URL */
++
++/* same as 301 except that the browser MUST retry with the same method */
++const char *HTTP_308 =
++      "HTTP/1.1 308 Permanent Redirect\r\n"
++      "Content-length: 0\r\n"
++      "Location: "; /* not terminated since it will be concatenated with the URL */
++
+ /* Warning: this one is an sprintf() fmt string, with <realm> as its only argument */
+ const char *HTTP_401_fmt =
+       "HTTP/1.0 401 Unauthorized\r\n"
+@@ -3355,6 +3369,12 @@ int http_process_req_common(struct session *s, struct buffer *req, int an_bit, s
+                       /* build redirect message */
+                       switch(rule->code) {
++                      case 308:
++                              msg_fmt = HTTP_308;
++                              break;
++                      case 307:
++                              msg_fmt = HTTP_307;
++                              break;
+                       case 303:
+                               msg_fmt = HTTP_303;
+                               break;
+-- 
+1.8.1.5
+
diff --git a/net/haproxy/patches/0037-MINOR-http-status-301-should-not-be-marked-non-cache.patch b/net/haproxy/patches/0037-MINOR-http-status-301-should-not-be-marked-non-cache.patch
new file mode 100644 (file)
index 0000000..01b06c8
--- /dev/null
@@ -0,0 +1,28 @@
+From 6c9ba3562cf57dc033a52c0973962c642b3aaf18 Mon Sep 17 00:00:00 2001
+From: Yves Lafon <ylafon@w3.org>
+Date: Mon, 11 Mar 2013 11:06:05 -0400
+Subject: [PATCH 37/42] MINOR: http: status 301 should not be marked
+ non-cacheable
+
+Also, browsers behaviour is inconsistent regarding the Cache-Control
+header field on a 301.
+(cherry picked from commit e267421e93eb35272a104c9c8fa6878880f42be8)
+---
+ src/proto_http.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/src/proto_http.c b/src/proto_http.c
+index 8d9d8e8..a52c038 100644
+--- a/src/proto_http.c
++++ b/src/proto_http.c
+@@ -73,7 +73,6 @@ const struct chunk http_100_chunk = {
+ /* Warning: no "connection" header is provided with the 3xx messages below */
+ const char *HTTP_301 =
+       "HTTP/1.1 301 Moved Permanently\r\n"
+-      "Cache-Control: no-cache\r\n"
+       "Content-length: 0\r\n"
+       "Location: "; /* not terminated since it will be concatenated with the URL */
+-- 
+1.8.1.5
+
diff --git a/net/haproxy/patches/0038-DOC-mention-the-new-HTTP-307-and-308-redirect-statue.patch b/net/haproxy/patches/0038-DOC-mention-the-new-HTTP-307-and-308-redirect-statue.patch
new file mode 100644 (file)
index 0000000..77135ce
--- /dev/null
@@ -0,0 +1,47 @@
+From 89c12b19f9e42976c9c205cd1a42bb2e148b3235 Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Fri, 29 Mar 2013 19:28:11 +0100
+Subject: [PATCH 38/42] DOC: mention the new HTTP 307 and 308 redirect statues
+ (cherry picked from commit b67fdc4cd8bde202f2805d98683ddab929469a05)
+
+---
+ doc/configuration.txt | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/doc/configuration.txt b/doc/configuration.txt
+index 20b89c2..9a99267 100644
+--- a/doc/configuration.txt
++++ b/doc/configuration.txt
+@@ -309,6 +309,8 @@ Haproxy may emit the following status codes by itself :
+    301  when performing a redirection, depending on the configured code
+    302  when performing a redirection, depending on the configured code
+    303  when performing a redirection, depending on the configured code
++   307  when performing a redirection, depending on the configured code
++   308  when performing a redirection, depending on the configured code
+    400  for an invalid or too large request
+    401  when an authentication is required to perform the action (when
+         accessing the stats page)
+@@ -4057,12 +4059,14 @@ redirect prefix   <to> [code <code>] <option> [{if | unless} <condition>]
+               URL.
+     <code>    The code is optional. It indicates which type of HTTP redirection
+-              is desired. Only codes 301, 302 and 303 are supported, and 302 is
+-              used if no code is specified. 301 means "Moved permanently", and
+-              a browser may cache the Location. 302 means "Moved permanently"
+-              and means that the browser should not cache the redirection. 303
+-              is equivalent to 302 except that the browser will fetch the
+-              location with a GET method.
++              is desired. Only codes 301, 302, 303, 307 and 308 are supported,
++              with 302 used by default if no code is specified. 301 means
++              "Moved permanently", and a browser may cache the Location. 302
++              means "Moved permanently" and means that the browser should not
++              cache the redirection. 303 is equivalent to 302 except that the
++              browser will fetch the location with a GET method. 307 is just
++              like 302 but makes it clear that the same method must be reused.
++              Likewise, 308 replaces 301 if the same method must be used.
+     <option>  There are several options which can be specified to adjust the
+               expected behaviour of a redirection :
+-- 
+1.8.1.5
+
diff --git a/net/haproxy/patches/0039-MEDIUM-poll-do-not-use-FD_-macros-anymore.patch b/net/haproxy/patches/0039-MEDIUM-poll-do-not-use-FD_-macros-anymore.patch
new file mode 100644 (file)
index 0000000..4a20f89
--- /dev/null
@@ -0,0 +1,193 @@
+From d9185dbab66e8ea3bafd1d43660ae44311da7a81 Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Sun, 31 Mar 2013 14:06:57 +0200
+Subject: [PATCH 39/42] MEDIUM: poll: do not use FD_* macros anymore
+
+Some recent glibc updates have added controls on FD_SET/FD_CLR/FD_ISSET
+that crash the program if it tries to use a file descriptor larger than
+FD_SETSIZE.
+
+Do not rely on FD_* macros anymore and replace them with bit fields.
+(cherry picked from commit 80da05a4cfb881663dc1f38a94d613f37e54552a)
+---
+ src/ev_poll.c | 87 +++++++++++++++++++++++++++++------------------------------
+ 1 file changed, 43 insertions(+), 44 deletions(-)
+
+diff --git a/src/ev_poll.c b/src/ev_poll.c
+index f5d011e..02e89ad 100644
+--- a/src/ev_poll.c
++++ b/src/ev_poll.c
+@@ -27,12 +27,25 @@
+ #include <proto/task.h>
+-static fd_set *fd_evts[2];
++static unsigned int *fd_evts[2];
+ /* private data */
+ static struct pollfd *poll_events = NULL;
++static inline unsigned int hap_fd_isset(int fd, unsigned int *evts)
++{
++      return evts[fd / (8*sizeof(*evts))] & (1U << (fd & (8*sizeof(*evts) - 1)));
++}
++
++static inline void hap_fd_set(int fd, unsigned int *evts)
++{
++      evts[fd / (8*sizeof(*evts))] |= 1U << (fd & (8*sizeof(*evts) - 1));
++}
++static inline void hap_fd_clr(int fd, unsigned int *evts)
++{
++      evts[fd / (8*sizeof(*evts))] &= ~(1U << (fd & (8*sizeof(*evts) - 1)));
++}
+ /*
+  * Benchmarks performed on a Pentium-M notebook show that using functions
+  * instead of the usual macros improve the FD_* performance by about 80%,
+@@ -40,43 +53,43 @@ static struct pollfd *poll_events = NULL;
+  */
+ REGPRM2 static int __fd_is_set(const int fd, int dir)
+ {
+-      return FD_ISSET(fd, fd_evts[dir]);
++      return hap_fd_isset(fd, fd_evts[dir]);
+ }
+ REGPRM2 static int __fd_set(const int fd, int dir)
+ {
+-      FD_SET(fd, fd_evts[dir]);
++      hap_fd_set(fd, fd_evts[dir]);
+       return 0;
+ }
+ REGPRM2 static int __fd_clr(const int fd, int dir)
+ {
+-      FD_CLR(fd, fd_evts[dir]);
++      hap_fd_clr(fd, fd_evts[dir]);
+       return 0;
+ }
+ REGPRM2 static int __fd_cond_s(const int fd, int dir)
+ {
+       int ret;
+-      ret = !FD_ISSET(fd, fd_evts[dir]);
++      ret = !hap_fd_isset(fd, fd_evts[dir]);
+       if (ret)
+-              FD_SET(fd, fd_evts[dir]);
++              hap_fd_set(fd, fd_evts[dir]);
+       return ret;
+ }
+ REGPRM2 static int __fd_cond_c(const int fd, int dir)
+ {
+       int ret;
+-      ret = FD_ISSET(fd, fd_evts[dir]);
++      ret = hap_fd_isset(fd, fd_evts[dir]);
+       if (ret)
+-              FD_CLR(fd, fd_evts[dir]);
++              hap_fd_clr(fd, fd_evts[dir]);
+       return ret;
+ }
+ REGPRM1 static void __fd_rem(const int fd)
+ {
+-      FD_CLR(fd, fd_evts[DIR_RD]);
+-      FD_CLR(fd, fd_evts[DIR_WR]);
++      hap_fd_clr(fd, fd_evts[DIR_RD]);
++      hap_fd_clr(fd, fd_evts[DIR_WR]);
+ }
+ /*
+@@ -93,33 +106,20 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
+       unsigned rn, wn; /* read new, write new */
+       nbfd = 0;
+-      for (fds = 0; (fds * BITS_PER_INT) < maxfd; fds++) {
+-
+-              rn = ((int*)fd_evts[DIR_RD])[fds];
+-              wn = ((int*)fd_evts[DIR_WR])[fds];
++      for (fds = 0; (fds * 8*sizeof(**fd_evts)) < maxfd; fds++) {
++              rn = fd_evts[DIR_RD][fds];
++              wn = fd_evts[DIR_WR][fds];
+         
+-              if ((rn|wn)) {
+-                      for (count = 0, fd = fds * BITS_PER_INT; count < BITS_PER_INT && fd < maxfd; count++, fd++) {
+-#define FDSETS_ARE_INT_ALIGNED
+-#ifdef FDSETS_ARE_INT_ALIGNED
+-
+-#define WE_REALLY_KNOW_THAT_FDSETS_ARE_INTS
+-#ifdef WE_REALLY_KNOW_THAT_FDSETS_ARE_INTS
+-                              sr = (rn >> count) & 1;
+-                              sw = (wn >> count) & 1;
+-#else
+-                              sr = FD_ISSET(fd&(BITS_PER_INT-1), (typeof(fd_set*))&rn);
+-                              sw = FD_ISSET(fd&(BITS_PER_INT-1), (typeof(fd_set*))&wn);
+-#endif
+-#else
+-                              sr = FD_ISSET(fd, fd_evts[DIR_RD]);
+-                              sw = FD_ISSET(fd, fd_evts[DIR_WR]);
+-#endif
+-                              if ((sr|sw)) {
+-                                      poll_events[nbfd].fd = fd;
+-                                      poll_events[nbfd].events = (sr ? POLLIN : 0) | (sw ? POLLOUT : 0);
+-                                      nbfd++;
+-                              }
++              if (!(rn|wn))
++                      continue;
++
++              for (count = 0, fd = fds * 8*sizeof(**fd_evts); count < 8*sizeof(**fd_evts) && fd < maxfd; count++, fd++) {
++                      sr = (rn >> count) & 1;
++                      sw = (wn >> count) & 1;
++                      if ((sr|sw)) {
++                              poll_events[nbfd].fd = fd;
++                              poll_events[nbfd].events = (sr ? POLLIN : 0) | (sw ? POLLOUT : 0);
++                              nbfd++;
+                       }
+               }                 
+       }
+@@ -149,14 +149,14 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
+               /* ok, we found one active fd */
+               status--;
+-              if (FD_ISSET(fd, fd_evts[DIR_RD])) {
++              if (hap_fd_isset(fd, fd_evts[DIR_RD])) {
+                       if (fdtab[fd].state == FD_STCLOSE)
+                               continue;
+                       if (poll_events[count].revents & ( POLLIN | POLLERR | POLLHUP ))
+                               fdtab[fd].cb[DIR_RD].f(fd);
+               }
+         
+-              if (FD_ISSET(fd, fd_evts[DIR_WR])) {
++              if (hap_fd_isset(fd, fd_evts[DIR_WR])) {
+                       if (fdtab[fd].state == FD_STCLOSE)
+                               continue;
+                       if (poll_events[count].revents & ( POLLOUT | POLLERR | POLLHUP ))
+@@ -174,21 +174,20 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
+ REGPRM1 static int _do_init(struct poller *p)
+ {
+       __label__ fail_swevt, fail_srevt, fail_pe;
+-      int fd_set_bytes;
++      int fd_evts_bytes;
+       p->private = NULL;
+-      fd_set_bytes = sizeof(fd_set) * (global.maxsock + FD_SETSIZE - 1) / FD_SETSIZE;
++      fd_evts_bytes = (global.maxsock + sizeof(**fd_evts) - 1) / sizeof(**fd_evts) * sizeof(**fd_evts);
+-      poll_events = (struct pollfd*)
+-              calloc(1, sizeof(struct pollfd) * global.maxsock);
++      poll_events = calloc(1, sizeof(struct pollfd) * global.maxsock);
+       if (poll_events == NULL)
+               goto fail_pe;
+               
+-      if ((fd_evts[DIR_RD] = (fd_set *)calloc(1, fd_set_bytes)) == NULL)
++      if ((fd_evts[DIR_RD] = calloc(1, fd_evts_bytes)) == NULL)
+               goto fail_srevt;
+-      if ((fd_evts[DIR_WR] = (fd_set *)calloc(1, fd_set_bytes)) == NULL)
++      if ((fd_evts[DIR_WR] = calloc(1, fd_evts_bytes)) == NULL)
+               goto fail_swevt;
+       return 1;
+-- 
+1.8.1.5
+
diff --git a/net/haproxy/patches/0040-BUG-MAJOR-ev_select-disable-the-select-poller-if-max.patch b/net/haproxy/patches/0040-BUG-MAJOR-ev_select-disable-the-select-poller-if-max.patch
new file mode 100644 (file)
index 0000000..1381eb2
--- /dev/null
@@ -0,0 +1,77 @@
+From f4096052b9397e29c3638651e7487c047081c00c Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Sun, 31 Mar 2013 14:41:15 +0200
+Subject: [PATCH 40/42] BUG/MAJOR: ev_select: disable the select() poller if
+ maxsock > FD_SETSIZE
+
+Some recent glibc updates have added controls on FD_SET/FD_CLR/FD_ISSET
+that crash the program if it tries to use a file descriptor larger than
+FD_SETSIZE.
+
+For this reason, we now control the compatibility between global.maxsock
+and FD_SETSIZE, and refuse to use select() if there too many FDs are
+expected to be used. Note that on Solaris, FD_SETSIZE is already forced
+to 65536, and that FreeBSD and OpenBSD allow it to be redefined, though
+this is not needed thanks to kqueue which is much more efficient.
+
+In practice, since poll() is enabled on all targets, it should not cause
+any problem, unless it is explicitly disabled.
+
+This change must be backported to 1.4 because the crashes caused by glibc
+have already been reported on this version.
+(cherry picked from commit 3fa87b1db95bc4d6640999462bdae620bff147c6)
+---
+ src/ev_select.c |  7 +++++++
+ src/haproxy.c   | 11 ++++++++++-
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/src/ev_select.c b/src/ev_select.c
+index 5a87282..1f35b54 100644
+--- a/src/ev_select.c
++++ b/src/ev_select.c
+@@ -170,6 +170,10 @@ REGPRM1 static int _do_init(struct poller *p)
+       int fd_set_bytes;
+       p->private = NULL;
++
++      if (global.maxsock > FD_SETSIZE)
++              goto fail_revt;
++
+       fd_set_bytes = sizeof(fd_set) * (global.maxsock + FD_SETSIZE - 1) / FD_SETSIZE;
+       if ((tmp_evts[DIR_RD] = (fd_set *)calloc(1, fd_set_bytes)) == NULL)
+@@ -217,6 +221,9 @@ REGPRM1 static void _do_term(struct poller *p)
+  */
+ REGPRM1 static int _do_test(struct poller *p)
+ {
++      if (global.maxsock > FD_SETSIZE)
++              return 0;
++
+       return 1;
+ }
+diff --git a/src/haproxy.c b/src/haproxy.c
+index c302143..1d588e1 100644
+--- a/src/haproxy.c
++++ b/src/haproxy.c
+@@ -711,7 +711,16 @@ void init(int argc, char **argv)
+               list_pollers(stderr);
+       if (!init_pollers()) {
+-              Alert("No polling mechanism available.\n");
++              Alert("No polling mechanism available.\n"
++                    "  It is likely that haproxy was built with TARGET=generic and that FD_SETSIZE\n"
++                    "  is too low on this platform to support maxconn and the number of listeners\n"
++                    "  and servers. You should rebuild haproxy specifying your system using TARGET=\n"
++                    "  in order to support other polling systems (poll, epoll, kqueue) or reduce the\n"
++                    "  global maxconn setting to accomodate the system's limitation. For reference,\n"
++                    "  FD_SETSIZE=%d on this system, global.maxconn=%d resulting in a maximum of\n"
++                    "  %d file descriptors. You should thus reduce global.maxconn by %d. Also,\n"
++                    "  check build settings using 'haproxy -vv'.\n\n",
++                    FD_SETSIZE, global.maxconn, global.maxsock, (global.maxsock + 1 - FD_SETSIZE) / 2);
+               exit(1);
+       }
+       if (global.mode & (MODE_VERBOSE|MODE_DEBUG)) {
+-- 
+1.8.1.5
+
diff --git a/net/haproxy/patches/0041-BUILD-enable-poll-by-default-in-the-makefile.patch b/net/haproxy/patches/0041-BUILD-enable-poll-by-default-in-the-makefile.patch
new file mode 100644 (file)
index 0000000..d82e04c
--- /dev/null
@@ -0,0 +1,60 @@
+From 4c5a09bb3c62070f139159378a8d68897b7ec8d6 Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Tue, 2 Apr 2013 08:14:29 +0200
+Subject: [PATCH 41/42] BUILD: enable poll() by default in the makefile
+
+This allows to build haproxy for unknown targets and still have poll().
+If for any reason a target does not support it, just passing USE_POLL=""
+disables it.
+(cherry picked from commit 32e65ef62570cbace7368ebe7262b48c28b31bb7)
+---
+ Makefile | 5 ++++-
+ README   | 9 ++++++++-
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 8d82543..f4dbccd 100644
+--- a/Makefile
++++ b/Makefile
+@@ -172,7 +172,10 @@ LDFLAGS = $(ARCH_FLAGS) -g
+ # Depending on the target platform, some options are set, as well as some
+ # CFLAGS and LDFLAGS. The USE_* values are set to "implicit" so that they are
+ # not reported in the build options string. You should not have to change
+-# anything there.
++# anything there. poll() is always supported, unless explicitly disabled by
++# passing USE_POLL="" on the make command line.
++USE_POLL   = default
++
+ ifeq ($(TARGET),generic)
+   # generic system target has nothing specific
+   USE_POLL   = implicit
+diff --git a/README b/README
+index aca83f9..c99897e 100644
+--- a/README
++++ b/README
+@@ -12,7 +12,7 @@
+ To build haproxy, you will need :
+   - GNU make. Neither Solaris nor OpenBSD's make work with the GNU Makefile.
+     However, specific Makefiles for BSD and OSX are provided.
+-  - GCC between 2.91 and 4.5.0. Others may work, but not tested.
++  - GCC between 2.91 and 4.7. Others may work, but not tested.
+   - GNU ld
+ Also, you might want to build with libpcre support, which will provide a very
+@@ -100,6 +100,13 @@ otherwise __fd_select() will be used while not being present in the libc.
+ If you get build errors because of strange symbols or section mismatches,
+ simply remove -g from DEBUG_CFLAGS.
++You can easily define your own target with the GNU Makefile. Unknown targets
++are processed with no default option except USE_POLL=default. So you can very
++well use that property to define your own set of options. USE_POLL can even be
++disabled by setting USE_POLL="". For example :
++
++    $ gmake TARGET=tiny USE_POLL="" TARGET_CFLAGS=-fomit-frame-pointer
++
+ 2) How to install it
+ --------------------
+-- 
+1.8.1.5
+
diff --git a/net/haproxy/patches/0042-BUILD-add-explicit-support-for-Mac-OS-X.patch b/net/haproxy/patches/0042-BUILD-add-explicit-support-for-Mac-OS-X.patch
new file mode 100644 (file)
index 0000000..d0a87cc
--- /dev/null
@@ -0,0 +1,57 @@
+From 2d7b45e7321437c1f9c4d0f2c46a793ef9d059c0 Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Tue, 2 Apr 2013 08:17:43 +0200
+Subject: [PATCH 42/42] BUILD: add explicit support for Mac OS/X
+
+The "osx" target may now be passed in the TARGET variable. It supports
+the same features as FreeBSD and allows its users to use the GNU makefile
+instead of the platform-specific makefile which lacks some features.
+(cherry picked from commit 8624cab29c52db9052bf022683cfd3d11369cc0d)
+---
+ Makefile | 8 ++++++++
+ README   | 3 ++-
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index f4dbccd..57692fe 100644
+--- a/Makefile
++++ b/Makefile
+@@ -245,6 +245,13 @@ ifeq ($(TARGET),freebsd)
+   USE_TPROXY     = implicit
+   USE_LIBCRYPT   = implicit
+ else
++ifeq ($(TARGET),osx)
++  # This is for Mac OS/X
++  USE_POLL       = implicit
++  USE_KQUEUE     = implicit
++  USE_TPROXY     = implicit
++  USE_LIBCRYPT   = implicit
++else
+ ifeq ($(TARGET),openbsd)
+   # This is for OpenBSD >= 3.0
+   USE_POLL       = implicit
+@@ -267,6 +274,7 @@ ifeq ($(TARGET),cygwin)
+ endif # cygwin
+ endif # aix52
+ endif # openbsd
++endif # osx
+ endif # freebsd
+ endif # solaris
+ endif # linux2628
+diff --git a/README b/README
+index c99897e..7897cb3 100644
+--- a/README
++++ b/README
+@@ -28,7 +28,8 @@ and assign it to the TARGET variable :
+   - linux2628   for Linux 2.6.28 and above (enables splice and tproxy)
+   - solaris     for Solaris 8 or 10 (others untested)
+   - freebsd     for FreeBSD 5 to 8.0 (others untested)
+-  - openbsd     for OpenBSD 3.1 to 4.6 (others untested)
++  - osx         for Mac OS/X
++  - openbsd     for OpenBSD 3.1 to 5.2 (others untested)
+   - aix52       for AIX 5.2
+   - cygwin      for Cygwin
+   - generic     for any other OS.
+-- 
+1.8.1.5
+