Ported from mod_accesslog.c by Colin Phipps <cph@moria.org.uk>
Index: src/log.c
===================================================================
--- src/log.c	(revision 896)
+++ src/log.c	(working copy)
@@ -31,6 +31,75 @@
 # define O_LARGEFILE 0
 #endif
 
+static int open_logfile_or_pipe(server *srv, const char* logfile) {
+	int fd;
+
+	if (logfile[0] == '|') {
+#ifdef HAVE_FORK
+		/* create write pipe and spawn process */
+		
+		int to_log_fds[2];
+		pid_t pid;
+		int i;
+		
+		if (pipe(to_log_fds)) {
+			log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed: ", strerror(errno));
+			return HANDLER_ERROR;
+		}
+		
+		/* fork, execve */
+		switch (pid = fork()) {
+		case 0: 
+			/* child */
+			
+			close(STDIN_FILENO);
+
+			/* dup the filehandle to STDIN */
+			
+			if (dup2(to_log_fds[0], STDIN_FILENO) == STDIN_FILENO) {
+
+				close(to_log_fds[0]);
+				/* not needed */
+				close(to_log_fds[1]);
+				
+				/* we don't need the client socket */
+				for (i = 3; i < 256; i++) {
+					close(i);
+				}
+			
+				/* exec the log-process (skip the | ) */
+				execl("/bin/sh", "sh", "-c", logfile + 1, NULL);
+			}
+
+			log_error_write(srv, __FILE__, __LINE__, "sss", 
+					"spawning error-log process failed: ", strerror(errno), 
+					logfile + 1);
+			
+			exit(-1);
+			break;
+		case -1:
+			/* error */
+			log_error_write(srv, __FILE__, __LINE__, "ss", "fork failed: ", strerror(errno));
+			return -1;
+		default:
+			close(to_log_fds[0]);
+			
+			fd = to_log_fds[1];
+		}
+
+#else
+		return -1;
+#endif
+	} else if (-1 == (fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
+		log_error_write(srv, __FILE__, __LINE__, "SSSS", 
+				"opening errorlog '", logfile,
+				"' failed: ", strerror(errno));
+		
+		return -1;
+	}
+	return fd;
+}
+
 /** 
  * open the errorlog
  * 
@@ -58,11 +127,7 @@
 	} else if (!buffer_is_empty(srv->srvconf.errorlog_file)) {
 		const char *logfile = srv->srvconf.errorlog_file->ptr;
 		
-		if (-1 == (srv->errorlog_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
-			log_error_write(srv, __FILE__, __LINE__, "SSSS", 
-					"opening errorlog '", logfile,
-					"' failed: ", strerror(errno));
-			
+		if (-1 == (srv->errorlog_fd = open_logfile_or_pipe(srv, logfile))) {
 			return -1;
 		}
 #ifdef FD_CLOEXEC
@@ -107,7 +172,7 @@
 		
 		int new_fd;
 		
-		if (-1 == (new_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
+		if (-1 == (new_fd = open_logfile_or_pipe(srv, logfile))) {
 			/* write to old log */
 			log_error_write(srv, __FILE__, __LINE__, "SSSSS", 
 					"cycling errorlog '", logfile,
