* released 1.1.27
* the configurable HTTP health check introduced in 1.1.23 revealed a shameful
  bug : the code still assumed that HTTP requests were the same size as the
  original ones (22 bytes), and failed if they were not.
* added support for pidfiles.
diff --git a/CHANGELOG b/CHANGELOG
index 2efba80..c3c2046 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,12 @@
 ChangeLog :
 ===========
 
+2003/10/27 : 1.1.27
+  - the configurable HTTP health check introduced in 1.1.23 revealed a shameful
+    bug : the code still assumed that HTTP requests were the same size as the
+    original ones (22 bytes), and failed if they were not.
+  - added support for pidfiles.
+
 2003/10/22 : 1.1.26
   - the fix introduced in 1.1.25 for client timeouts while waiting for servers
     broke almost all compatibility with POST requests, because the proxy
diff --git a/doc/haproxy-en.txt b/doc/haproxy-en.txt
index a4bbf01..ad82521 100644
--- a/doc/haproxy-en.txt
+++ b/doc/haproxy-en.txt
@@ -1,9 +1,9 @@
 
          		     H A - P r o x y
          		     ---------------
-         		      version 1.1.25
+         		      version 1.1.27
 			      willy tarreau
-			       2003/10/15
+			       2003/10/27
 
 ============
 | Abstract |
@@ -35,6 +35,8 @@
     -N <high limit for the per-proxy number of simultaneous connections>
     -d starts in foregreound with debugging mode enabled
     -D starts in daemon mode
+    -p <pidfile> asks the process to write down each of its children's
+       pids to this file in daemon mode.
     -s shows statistics (only if compiled in)
     -l shows even more statistics (implies '-s')
 
@@ -92,6 +94,7 @@
   - daemon
   - debug
   - quiet
+  - pidfile <file>
 
 1.1) Event logging
 ------------------
@@ -231,6 +234,28 @@
 	nbproc	2
 
 
+1.6) Helping process management
+-------------------------------
+Haproxy now supports the notion of pidfile. If the '-p' command line argument,
+or the 'pidfile' global option is followed with a file name, this file will be
+removed, then filled with all children's pids, one per line (only in daemon
+mode). This file is NOT within the chroot, which allows to work with a readonly
+ chroot. It will be owned by the user starting the process, and will have
+permissions 0644.
+
+Example :
+---------
+
+    global
+        daemon
+        quiet
+        nbproc 2
+        pidfile /var/run/haproxy-private.pid
+
+    # to stop only those processes among others :
+    # kill $(</var/run/haproxy-private.pid)
+
+
 2) Declaration of a listening service
 =====================================
 
diff --git a/doc/haproxy-fr.txt b/doc/haproxy-fr.txt
index 596531d..f1b08e8 100644
--- a/doc/haproxy-fr.txt
+++ b/doc/haproxy-fr.txt
@@ -1,9 +1,9 @@
 
          		     H A - P r o x y
          		     ---------------
-         		      version 1.1.25
+         		      version 1.1.27
 			      willy tarreau
-			       2003/10/15
+			       2003/10/27
 
 ================
 | Introduction |
@@ -37,6 +37,8 @@
     -N <nombre maximal de connexions simultanées par proxy>
     -d active le mode debug
     -D passe en daemon
+    -p <fichier> indique au processus père qu'il doit écrire les PIDs de ses
+       fils dans ce fichier en mode démon.
     -s affiche les statistiques (si option compilée)
     -l ajoute des informations aux statistiques
 
@@ -95,6 +97,7 @@
   - daemon
   - debug
   - quiet
+  - pidfile <fichier>
 
 1.1) Journalisation des événements
 ----------------------------------
@@ -199,7 +202,7 @@
 	gid	30000
 	chroot  /var/chroot/haproxy
 
-1.4) modes de fonctionnement
+1.4) Modes de fonctionnement
 ----------------------------
 Le service peut fonctionner dans plusieurs modes :
   - avant- / arrière-plan
@@ -222,7 +225,7 @@
 entre les clients et les serveurs. Ce mode est incompatible avec les options
 'daemon' et 'quiet' pour des raisons de bon sens.
 
-1.5) accroissement de la capacité de traitement
+1.5) Accroissement de la capacité de traitement
 -----------------------------------------------
 Sur des machines multi-processeurs, il peut sembler gâché de n'utiliser qu'un
 processeur pour effectuer les tâches de relayage, même si les charges
@@ -241,6 +244,29 @@
 	quiet
 	nbproc	2
 
+1.6) Simplification de la gestion des processus
+-----------------------------------------------
+Haproxy supporte dorénavant la notion de fichiers de pid (-> pidfiles). Si le
+paramètre '-p' de ligne de commande, ou l'option globale 'pidfile' sont suivis
+d'un nom de fichier, alors ce fichier sera supprimé puis recréé et contiendra
+le numéro de PID des processus fils, à raison d'un par ligne (valable
+uniquement en mode démon). Ce fichier n'est PAS relatif au cloisonnement chroot
+afin de rester compatible avec un répertoire protégé en lecture seule. Il
+appartiendra à l'utilisateur ayant lancé le processus, et disposera des droits
+0644.
+
+Exemple :
+---------
+
+    global
+        daemon
+        quiet
+        nbproc 2
+        pidfile /var/run/haproxy-private.pid
+
+    # pour stopper seulement ces processus parmi d'autres :
+    # kill $(</var/run/haproxy-private.pid)
+
 
 2) Définition d'un service en écoute
 ====================================
diff --git a/examples/config.rc.haproxy b/examples/config.rc.haproxy
index 067f07a..5340495 100644
--- a/examples/config.rc.haproxy
+++ b/examples/config.rc.haproxy
@@ -1,3 +1,6 @@
-service haproxy
-	config /etc/haproxy/haproxy.cfg
+service haproxy ext
+	config /etc/haproxy/haproxy-ext.cfg
+
+service haproxy int
+	config /etc/haproxy/haproxy-int.cfg
 
diff --git a/examples/init.haproxy.flx0 b/examples/init.haproxy.flx0
index aa5f0cb..4b73bd8 100644
--- a/examples/init.haproxy.flx0
+++ b/examples/init.haproxy.flx0
@@ -4,7 +4,7 @@
 
 option	config		standard_option	/etc/haproxy/haproxy.cfg
 option	bin		reserved_option	/usr/sbin/haproxy
-option	cmdline		reserved_option	'$bin -q -D -f ${opt_config}'
+option	cmdline		reserved_option	'$bin -f ${opt_config} -p ${pidfile} -D -q'
 
 function do_help {
     echo "Usage: ${0##*/} <status|start|stop|help>"
@@ -15,6 +15,10 @@
     exit 1 
 }
 
+# assign default values to options and variables before parsing the cfg file
+function fct_begin_section {
+    pidfile="/var/run/haproxy${2:+-$2}.pid"
+}
 
 load_config
 
diff --git a/haproxy.c b/haproxy.c
index 776a235..bdee43d 100644
--- a/haproxy.c
+++ b/haproxy.c
@@ -53,8 +53,8 @@
 #include <linux/netfilter_ipv4.h>
 #endif
 
-#define HAPROXY_VERSION "1.1.26"
-#define HAPROXY_DATE	"2003/10/22"
+#define HAPROXY_VERSION "1.1.27"
+#define HAPROXY_DATE	"2003/10/27"
 
 /* this is for libc5 for example */
 #ifndef TCP_NODELAY
@@ -491,6 +491,7 @@
     int maxsock;		/* max # of sockets */
     int mode;
     char *chroot;
+    char *pidfile;
     int logfac1, logfac2;
     int loglev1, loglev2;
     struct sockaddr_in logsrv1, logsrv2;
@@ -677,7 +678,7 @@
 #if STATTIME > 0
 	    "sl"
 #endif
-	    "D ] [ -n <maxconn> ] [ -N <maxpconn> ]\n"
+	    "D ] [ -n <maxconn> ] [ -N <maxpconn> ] [ -p <pidfile> ]\n"
 	    "        -v displays version\n"
 	    "        -d enters debug mode\n"
 #if STATTIME > 0
@@ -687,7 +688,8 @@
 	    "        -D goes daemon ; implies -q\n"
 	    "        -q quiet mode : don't display messages\n"
 	    "        -n sets the maximum total # of connections (%d)\n"
-	    "        -N sets the default, per-proxy maximum # of connections (%d)\n\n",
+	    "        -N sets the default, per-proxy maximum # of connections (%d)\n"
+	    "        -p writes pids of all children to this file\n\n",
 	    name, DEFAULT_MAXCONN, cfg_maxpconn);
     exit(1);
 }
@@ -2226,7 +2228,7 @@
 #else
 	    ret = send(fd, s->proxy->check_req, s->proxy->check_len, MSG_DONTWAIT | MSG_NOSIGNAL);
 #endif
-	    if (ret == 22) {
+	    if (ret == s->proxy->check_len) {
 		FD_SET(fd, StaticReadEvent);   /* prepare for reading reply */
 		FD_CLR(fd, StaticWriteEvent);  /* nothing more to write */
 		return 0;
@@ -4337,6 +4339,17 @@
 	}
 	global.chroot = strdup(args[1]);
     }
+    else if (!strcmp(args[0], "pidfile")) {
+	if (global.pidfile != NULL) {
+	    Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
+	    return 0;
+	}
+	if (*(args[1]) == 0) {
+	    Alert("parsing [%s:%d] : '%s' expects a file name as an argument.\n", file, linenum, args[0]);
+	    return -1;
+	}
+	global.pidfile = strdup(args[1]);
+    }
     else if (!strcmp(args[0], "log")) {  /* syslog server address */
 	struct sockaddr_in *sa;
 	int facility, level;
@@ -5614,6 +5627,7 @@
     int arg_mode = 0;	/* MODE_DEBUG, ... */
     char *old_argv = *argv;
     char *tmp;
+    char *cfg_pidfile = NULL;
     int cfg_maxconn = 0;	/* # of simultaneous connections, (-n) */
 
     if (1<<INTBITS != sizeof(int)*8) {
@@ -5661,6 +5675,7 @@
 		case 'n' : cfg_maxconn = atol(*argv); break;
 		case 'N' : cfg_maxpconn = atol(*argv); break;
 		case 'f' : cfg_cfgfile = *argv; break;
+		case 'p' : cfg_pidfile = *argv; break;
 		default: usage(old_argv);
 		}
 	    }
@@ -5683,6 +5698,12 @@
     if (cfg_maxconn > 0)
 	global.maxconn = cfg_maxconn;
 
+    if (cfg_pidfile) {
+	if (global.pidfile)
+	    free(global.pidfile);
+	global.pidfile = strdup(cfg_pidfile);
+    }
+
     if (global.maxconn == 0)
 	global.maxconn = DEFAULT_MAXCONN;
 
@@ -5802,6 +5823,7 @@
 
 
 int main(int argc, char **argv) {
+    FILE *pidfile = NULL;
     init(argc, argv);
 
     if (global.mode & MODE_QUIET) {
@@ -5824,7 +5846,17 @@
     if (start_proxies() < 0)
 	exit(1);
 
-    /* open log files */
+    /* open log & pid files before the chroot */
+    if (global.mode & MODE_DAEMON && global.pidfile != NULL) {
+	int pidfd;
+	unlink(global.pidfile);
+	pidfd = open(global.pidfile, O_CREAT | O_WRONLY | O_TRUNC, 0644);
+	if (pidfd < 0) {
+	    Alert("[%s.main()] Cannot create pidfile %s\n", argv[0], global.pidfile);
+	    exit(1);
+	}
+	pidfile = fdopen(pidfd, "w");
+    }
 
     /* chroot if needed */
     if (global.chroot != NULL) {
@@ -5859,7 +5891,16 @@
 	    }
 	    else if (ret == 0) /* child breaks here */
 		break;
+	    if (pidfile != NULL) {
+		fprintf(pidfile, "%d\n", ret);
+		fflush(pidfile);
+	    }
 	}
+	/* close the pidfile both in children and father */
+	if (pidfile != NULL)
+	    fclose(pidfile);
+	free(global.pidfile);
+
 	if (proc == global.nbproc)
 	    exit(0); /* parent must leave */