Project

General

Profile

Feature #296 » lighttpd-piperrorlog.patch

patch for trunk that adds a new errorlog type "pipe" and implements it - carenas, 2006-12-18 02:36

View differences:

trunk/src/log.c (working copy)
/**
* open the errorlog
*
* we have 3 possibilities:
* we have 4 possibilities:
* - stderr (default)
* - syslog
* - logfile
* - pipe
*
* if the open failed, report to the user and die
*
......
/* the errorlog */
int fd;
enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG } mode;
enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG, ERRORLOG_PIPE } mode;
buffer *buf;
time_t cached_ts;
......
TRACE("%s", "server stopped");
switch(err->mode) {
case ERRORLOG_PIPE: /* fall through */
case ERRORLOG_FILE:
close(err->fd);
break;
......
if (use_syslog) {
err->mode = ERRORLOG_SYSLOG;
} else if (!buffer_is_empty(file)) {
if (-1 == (err->fd = open(file->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
log_error_write(NULL, __FILE__, __LINE__, "SBSS",
"opening errorlog '", file,
"' failed: ", strerror(errno));
if (*(char *)file->ptr == '|') {
#ifdef HAVE_FORK
/* create write pipe and spawn process */
int to_log_fds[2];
pid_t pid;
if (pipe(to_log_fds)) {
log_error_write(NULL, __FILE__, __LINE__, "ss",
"pipe failed: ", strerror(errno));
return -1;
}
/* fork, execve */
switch (pid = fork()) {
case 0:
/* child */
close(STDIN_FILENO);
dup2(to_log_fds[0], STDIN_FILENO);
close(to_log_fds[0]);
/* not needed */
close(to_log_fds[1]);
/* we don't need the client socket */
for (fd = 3; fd < 256; fd++) {
close(fd);
}
/* exec the log-process (skip the | )
*
*/
execl("/bin/sh", "sh", "-c", file->ptr + 1, NULL);
log_error_write(NULL, __FILE__, __LINE__, "ssb",
"spawning log-process failed: ",
strerror(errno), file->ptr + 1);
exit(-1);
break;
case -1:
/* error */
log_error_write(NULL, __FILE__, __LINE__, "ss", "fork failed:", strerror(errno));
break;
default:
close(to_log_fds[0]);
err->fd = to_log_fds[1];
break;
}
err->mode = ERRORLOG_PIPE;
#else
log_error_write(NULL, __FILE__, __LINE__, "SBS",
"opening errorlog '", file,"' impossible");
return -1;
#endif
} else {
if (-1 == (err->fd = open(file->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
log_error_write(NULL, __FILE__, __LINE__, "SBSS",
"opening errorlog '", file,
"' failed: ", strerror(errno));
return -1;
}
err->mode = ERRORLOG_FILE;
}
#ifdef FD_CLOEXEC
/* close fd on exec (cgi) */
fcntl(err->fd, F_SETFD, FD_CLOEXEC);
#endif
err->mode = ERRORLOG_FILE;
}
TRACE("%s", "server started");
......
*/
int log_error_cycle(void) {
/* only cycle if we are not in syslog-mode */
/* only cycle if the error log is a file */
errorlog *err = myconfig;
......
UNUSED(srv);
switch(err->mode) {
case ERRORLOG_PIPE: /* fall through */
case ERRORLOG_FILE:
case ERRORLOG_STDERR:
/* cache the generated timestamp */
......
va_end(ap);
switch(err->mode) {
case ERRORLOG_PIPE: /* fall through */
case ERRORLOG_FILE:
BUFFER_APPEND_STRING_CONST(err->buf, "\n");
write(err->fd, err->buf->ptr, err->buf->used - 1);
......
/* write b */
switch(err->mode) {
case ERRORLOG_PIPE: /* fall through */
case ERRORLOG_FILE:
buffer_append_string(b, "\r\n");
write(err->fd, b->ptr, b->used - 1);
(2-2/4)