Browse Source

Implement a clean way to open /dev/null and use it to close stdin/out/err in the needed places (#624)

- as stderr gets redirected to /dev/null before exec in childs, we cannot
   write to the log afterwards, so disabled that log messages too.


git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2163 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.20
Stefan Bühler 14 years ago
parent
commit
93e7167f84
  1. 1
      NEWS
  2. 39
      src/log.c
  3. 5
      src/log.h
  4. 2
      src/mod_accesslog.c
  5. 4
      src/mod_cgi.c
  6. 6
      src/mod_fastcgi.c
  7. 4
      src/mod_rrdtool.c
  8. 15
      src/server.c

1
NEWS

@ -24,6 +24,7 @@ NEWS
* Remove lighttpd.spec* from source, fixing all problems with it ;-)
* Do not rely on PATH_MAX (POSIX does not require it) (#580)
* Disable logging to access.log if filename is an empty string
* Implement a clean way to open /dev/null and use it to close stdin/out/err in the needed places (#624)
- 1.4.19 - 2008-03-10

39
src/log.c

@ -31,6 +31,29 @@
# define O_LARGEFILE 0
#endif
/* Close fd and _try_ to get a /dev/null for it instead.
* close() alone may trigger some bugs when a
* process opens another file and gets fd = STDOUT_FILENO or STDERR_FILENO
* and later tries to just print on stdout/stderr
*
* Returns 0 on success and -1 on failure (fd gets closed in all cases)
*/
int openDevNull(int fd) {
int tmpfd;
close(fd);
#if defined(__WIN32)
/* Cygwin should work with /dev/null */
tmpfd = open("nul", O_RDWR);
#else
tmpfd = open("/dev/null", O_RDWR);
#endif
if (tmpfd != -1 && tmpfd != fd) {
dup2(tmpfd, fd);
close(tmpfd);
}
return (tmpfd != -1) ? 0 : -1;
}
/**
* open the errorlog
*
@ -44,7 +67,6 @@
*/
int log_error_open(server *srv) {
int fd;
int close_stderr = 1;
#ifdef HAVE_SYSLOG_H
@ -78,15 +100,16 @@ int log_error_open(server *srv) {
/* don't close stderr for debugging purposes if run in valgrind */
if (RUNNING_ON_VALGRIND) close_stderr = 0;
#endif
if (srv->errorlog_mode == ERRORLOG_STDERR) close_stderr = 0;
/* move stderr to /dev/null */
if (close_stderr &&
-1 != (fd = open("/dev/null", O_WRONLY))) {
close(STDERR_FILENO);
dup2(fd, STDERR_FILENO);
close(fd);
if (srv->errorlog_mode == ERRORLOG_STDERR && srv->srvconf.dont_daemonize) {
/* We can only log to stderr in dont-daemonize mode;
* if we do daemonize and no errorlog file is specified, we log into /dev/null
*/
close_stderr = 0;
}
/* move stderr to /dev/null */
if (close_stderr) openDevNull(STDERR_FILENO);
return 0;
}

5
src/log.h

@ -3,6 +3,11 @@
#include "server.h"
/* Close fd and _try_ to get a /dev/null for it instead.
* Returns 0 on success and -1 on failure (fd gets closed in all cases)
*/
int openDevNull(int fd);
#define WP() log_error_write(srv, __FILE__, __LINE__, "");
int log_error_open(server *srv);

2
src/mod_accesslog.c

@ -498,6 +498,8 @@ SETDEFAULTS_FUNC(log_access_open) {
/* not needed */
close(to_log_fds[1]);
openDevNull(STDERR_FILENO);
/* we don't need the client socket */
for (i = 3; i < 256; i++) {
close(i);

4
src/mod_cgi.c

@ -987,6 +987,8 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
*c = '/';
}
openDevNull(STDERR_FILENO);
/* we don't need the client socket */
for (i = 3; i < 256; i++) {
if (i != srv->errorlog_fd) close(i);
@ -995,7 +997,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
/* exec the cgi */
execve(args[0], args, env.ptr);
log_error_write(srv, __FILE__, __LINE__, "sss", "CGI failed:", strerror(errno), args[0]);
/* log_error_write(srv, __FILE__, __LINE__, "sss", "CGI failed:", strerror(errno), args[0]); */
/* */
SEGFAULT();

6
src/mod_fastcgi.c

@ -937,6 +937,8 @@ static int fcgi_spawn_connection(server *srv,
close(fcgi_fd);
}
openDevNull(STDERR_FILENO);
/* we don't need the client socket */
for (i = 3; i < 256; i++) {
close(i);
@ -1000,8 +1002,8 @@ static int fcgi_spawn_connection(server *srv,
/* exec the cgi */
execve(arg.ptr[0], arg.ptr, env.ptr);
log_error_write(srv, __FILE__, __LINE__, "sbs",
"execve failed for:", host->bin_path, strerror(errno));
/* log_error_write(srv, __FILE__, __LINE__, "sbs",
"execve failed for:", host->bin_path, strerror(errno)); */
exit(errno);

4
src/mod_rrdtool.c

@ -148,6 +148,8 @@ int mod_rrd_create_pipe(server *srv, plugin_data *p) {
args[i++] = dash;
args[i++] = NULL;
openDevNull(STDERR_FILENO);
/* we don't need the client socket */
for (i = 3; i < 256; i++) {
close(i);
@ -156,7 +158,7 @@ int mod_rrd_create_pipe(server *srv, plugin_data *p) {
/* exec the cgi */
execv(args[0], args);
log_error_write(srv, __FILE__, __LINE__, "sss", "spawing rrdtool failed: ", strerror(errno), args[0]);
/* log_error_write(srv, __FILE__, __LINE__, "sss", "spawing rrdtool failed: ", strerror(errno), args[0]); */
/* */
SEGFAULT();

15
src/server.c

@ -573,19 +573,8 @@ int main (int argc, char **argv) {
}
/* close stdin and stdout, as they are not needed */
/* move stdin to /dev/null */
if (-1 != (fd = open("/dev/null", O_RDONLY))) {
close(STDIN_FILENO);
dup2(fd, STDIN_FILENO);
close(fd);
}
/* move stdout to /dev/null */
if (-1 != (fd = open("/dev/null", O_WRONLY))) {
close(STDOUT_FILENO);
dup2(fd, STDOUT_FILENO);
close(fd);
}
openDevNull(STDIN_FILENO);
openDevNull(STDOUT_FILENO);
if (0 != config_set_defaults(srv)) {
log_error_write(srv, __FILE__, __LINE__, "s",

Loading…
Cancel
Save