nghttpx: make early copy of stderr

This commit is contained in:
Tomasz Buchert 2015-08-13 11:01:37 +02:00
parent 900dcf4ced
commit 97566ce4e3
3 changed files with 31 additions and 3 deletions

View File

@ -564,6 +564,9 @@ void exec_binary_signal_cb(struct ev_loop *loop, ev_signal *w, int revents) {
} }
} }
// restores original stderr
util::restore_original_fds();
if (execve(argv[0], argv.get(), envp.get()) == -1) { if (execve(argv[0], argv.get(), envp.get()) == -1) {
auto error = errno; auto error = errno;
LOG(ERROR) << "execve failed: errno=" << error; LOG(ERROR) << "execve failed: errno=" << error;
@ -1763,6 +1766,9 @@ int main(int argc, char **argv) {
create_config(); create_config();
fill_default_config(); fill_default_config();
// make copy of stderr
util::store_original_fds();
// First open log files with default configuration, so that we can // First open log files with default configuration, so that we can
// log errors/warnings while reading configuration files. // log errors/warnings while reading configuration files.
reopen_log_files(); reopen_log_files();

View File

@ -657,9 +657,23 @@ std::string numeric_name(const struct sockaddr *sa, socklen_t salen) {
return host.data(); return host.data();
} }
static int STDERR_COPY = -1;
static int STDOUT_COPY = -1;
void store_original_fds() {
// consider dup'ing stdout too
STDERR_COPY = dup(STDERR_FILENO);
STDOUT_COPY = STDOUT_FILENO;
// no race here, since it is called early
make_socket_closeonexec(STDERR_COPY);
}
void restore_original_fds() {
dup2(STDERR_COPY, STDERR_FILENO);
}
void close_log_file(int &fd) { void close_log_file(int &fd) {
if (fd != STDERR_FILENO && fd != STDOUT_FILENO && fd != -1) { if (fd != STDERR_COPY && fd != STDOUT_COPY && fd != -1) {
close(fd); close(fd);
} }
fd = -1; fd = -1;
@ -669,12 +683,12 @@ int open_log_file(const char *path) {
if (strcmp(path, "/dev/stdout") == 0 || if (strcmp(path, "/dev/stdout") == 0 ||
strcmp(path, "/proc/self/fd/1") == 0) { strcmp(path, "/proc/self/fd/1") == 0) {
return STDOUT_FILENO; return STDOUT_COPY;
} }
if (strcmp(path, "/dev/stderr") == 0 || if (strcmp(path, "/dev/stderr") == 0 ||
strcmp(path, "/proc/self/fd/2") == 0) { strcmp(path, "/proc/self/fd/2") == 0) {
return STDERR_FILENO; return STDERR_COPY;
} }
#if defined O_CLOEXEC #if defined O_CLOEXEC

View File

@ -516,6 +516,14 @@ bool numeric_host(const char *hostname);
// failed, "unknown" is returned. // failed, "unknown" is returned.
std::string numeric_name(const struct sockaddr *sa, socklen_t salen); std::string numeric_name(const struct sockaddr *sa, socklen_t salen);
// Makes internal copy of stderr (and possibly stdout in the future),
// which is then used as pointer to /dev/stderr or /proc/self/fd/2
void store_original_fds();
// Restores the original stderr that was stored with copy_original_fds
// Used just before execv
void restore_original_fds();
// Closes |fd| which was returned by open_log_file (see below) // Closes |fd| which was returned by open_log_file (see below)
// and sets it to -1. In the case that |fd| points to stdout or // and sets it to -1. In the case that |fd| points to stdout or
// stderr, or is -1, the descriptor is not closed (but still set to -1). // stderr, or is -1, the descriptor is not closed (but still set to -1).