Feature #296 » lighttpd-1.4.x-piperrorlog.patch
src/mod_cgi.c (working copy) | ||
---|---|---|
*
|
||
* we feed the stderr of the CGI to our errorlog, if possible
|
||
*/
|
||
if (srv->errorlog_mode == ERRORLOG_FILE) {
|
||
if ((srv->errorlog_mode == ERRORLOG_FILE) || (srv->errorlog_mode == ERRORLOG_PIPE)) {
|
||
close(STDERR_FILENO);
|
||
dup2(srv->errorlog_fd, STDERR_FILENO);
|
||
}
|
src/base.h (working copy) | ||
---|---|---|
/* the errorlog */
|
||
int errorlog_fd;
|
||
enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG } errorlog_mode;
|
||
enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG, ERRORLOG_PIPE } errorlog_mode;
|
||
buffer *errorlog_buf;
|
||
fdevents *ev, *ev_ins;
|
src/mod_rrdtool.c (working copy) | ||
---|---|---|
close(STDERR_FILENO);
|
||
if (srv->errorlog_mode == ERRORLOG_FILE) {
|
||
if ((srv->errorlog_mode == ERRORLOG_FILE) || (srv->errorlog_mode == ERRORLOG_PIPE)) {
|
||
dup2(srv->errorlog_fd, STDERR_FILENO);
|
||
close(srv->errorlog_fd);
|
||
}
|
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
|
||
*
|
||
... | ... | |
} 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",
|
||
if (logfile[0] == '|') {
|
||
#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(srv, __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", logfile + 1, NULL);
|
||
|
||
log_error_write(srv, __FILE__, __LINE__, "sss",
|
||
"spawning log-process failed: ",
|
||
strerror(errno), logfile + 1);
|
||
exit(-1);
|
||
break;
|
||
case -1:
|
||
/* error */
|
||
log_error_write(srv, __FILE__, __LINE__, "ss", "fork failed:", strerror(errno));
|
||
break;
|
||
default:
|
||
close(to_log_fds[0]);
|
||
srv->errorlog_fd = to_log_fds[1];
|
||
break;
|
||
}
|
||
srv->errorlog_mode = ERRORLOG_PIPE;
|
||
#else
|
||
log_error_write(srv, __FILE__, __LINE__, "SSS",
|
||
"opening errorlog '", logfile,"' impossible");
|
||
return -1;
|
||
#endif
|
||
} else {
|
||
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));
|
||
return -1;
|
||
return -1;
|
||
}
|
||
srv->errorlog_mode = ERRORLOG_FILE;
|
||
}
|
||
#ifdef FD_CLOEXEC
|
||
/* close fd on exec (cgi) */
|
||
fcntl(srv->errorlog_fd, F_SETFD, FD_CLOEXEC);
|
||
#endif
|
||
srv->errorlog_mode = ERRORLOG_FILE;
|
||
}
|
||
log_error_write(srv, __FILE__, __LINE__, "s", "server started");
|
||
... | ... | |
*/
|
||
int log_error_cycle(server *srv) {
|
||
/* only cycle if we are not in syslog-mode */
|
||
/* only cycle if the error log is a file */
|
||
if (srv->errorlog_mode == ERRORLOG_FILE) {
|
||
const char *logfile = srv->srvconf.errorlog_file->ptr;
|
||
... | ... | |
log_error_write(srv, __FILE__, __LINE__, "s", "server stopped");
|
||
switch(srv->errorlog_mode) {
|
||
case ERRORLOG_PIPE: /* fall through */
|
||
case ERRORLOG_FILE:
|
||
close(srv->errorlog_fd);
|
||
break;
|
||
... | ... | |
va_list ap;
|
||
switch(srv->errorlog_mode) {
|
||
case ERRORLOG_PIPE:
|
||
case ERRORLOG_FILE:
|
||
case ERRORLOG_STDERR:
|
||
/* cache the generated timestamp */
|
||
... | ... | |
va_end(ap);
|
||
switch(srv->errorlog_mode) {
|
||
case ERRORLOG_PIPE: /* fall through */
|
||
case ERRORLOG_FILE:
|
||
BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
|
||
write(srv->errorlog_fd, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
|