MINOR: mworker: keep and clean the listeners

Keep the listeners that should be used in the master process and clean
them in the workers.
diff --git a/include/types/listener.h b/include/types/listener.h
index 09b1104..816d111 100644
--- a/include/types/listener.h
+++ b/include/types/listener.h
@@ -100,6 +100,7 @@
 #define LI_O_V4V6               0x0800  /* bind to IPv4/IPv6 on Linux >= 2.4.21 */
 #define LI_O_ACC_CIP            0x1000  /* find the proxied address in the NetScaler Client IP header */
 #define LI_O_INHERITED          0x2000  /* inherited FD from the parent process (fd@) */
+#define LI_O_MWORKER            0x4000  /* keep the FD open in the master but close it in the children */
 
 /* Note: if a listener uses LI_O_UNLIMITED, it is highly recommended that it adds its own
  * maxconn setting to the global.maxsock value so that its resources are reserved.
diff --git a/src/haproxy.c b/src/haproxy.c
index 9cf6742..d5345ba 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -617,11 +617,11 @@
 		list_for_each_entry_safe(l, l_next, &curproxy->conf.listeners, by_fe) {
 			/* does not close if the FD is inherited with fd@
 			 * from the parent process */
-			if (!(l->options & LI_O_INHERITED))
+			if (!(l->options & (LI_O_INHERITED|LI_O_MWORKER)))
 				unbind_listener(l);
-			/* remove the listener, but we might want to keep some
-			 * for the master in the future... */
-			delete_listener(l);
+			/* remove the listener, but not those we need in the master... */
+			if (!(l->options & LI_O_MWORKER))
+				delete_listener(l);
 		}
 	}
 }
diff --git a/src/listener.c b/src/listener.c
index a30d4fb..09ac50b 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -48,6 +48,8 @@
 	.list = LIST_HEAD_INIT(bind_keywords.list)
 };
 
+extern int master;
+
 struct xfer_sock_list *xfer_sock_list = NULL;
 
 /* This function adds the specified listener's file descriptor to the polling
@@ -81,6 +83,12 @@
 			listener->state = LI_FULL;
 		}
 	}
+	/* if this listener is supposed to be only in the master, close it in the workers */
+	if ((global.mode & MODE_MWORKER) &&
+	    (listener->options & LI_O_MWORKER) &&
+	    master == 0) {
+		do_unbind_listener(listener, 1);
+	}
 	HA_SPIN_UNLOCK(LISTENER_LOCK, &listener->lock);
 }