Unverified Commit a22fbab9 authored by teor's avatar teor
Browse files

log: Don't close file log fds that are being used by the err module

Instead, dup() file log fds, before passing them to the err module.

Closes 31613, part of 31594.
parent d02ced4c
......@@ -111,6 +111,12 @@ tor_log_get_sigsafe_err_fds(const int **out)
* other emergency condition. Ignore any beyond the first
* These fds must remain open even after the log module has shut down. (And
* they should remain open even while logs are being reconfigured.) Therefore,
* any fds closed by the log module should be dup()ed, and the duplicate fd
* should be given to the err module in fds. In particular, the log module
* closes the file log fds, but does not close the stdio log fds.
* If fds is NULL or n is 0, clears the list of error fds.
......@@ -664,13 +664,24 @@ tor_log_update_sigsafe_err_fds(void)
const logfile_t *lf;
int found_real_stderr = 0;
/* log_fds and err_fds contain matching entries: log_fds are the fds used by
* the log module, and err_fds are the fds used by the err module.
* For stdio logs, the log_fd and err_fd values are identical,
* and the err module closes the fd on shutdown.
* For file logs, the err_fd is a dup() of the log_fd,
* and the log and err modules both close their respective fds on shutdown.
* (Once all fds representing a file are closed, the underlying file is
* closed.)
int n_fds;
/* Reserve the first one for stderr. This is safe because when we daemonize,
* we dup2 /dev/null to stderr, */
* we dup2 /dev/null to stderr.
* For stderr, log_fds and err_fds are the same. */
log_fds[0] = err_fds[0] = STDERR_FILENO;
n_fds = 1;
for (lf = logfiles; lf; lf = lf->next) {
......@@ -684,25 +695,39 @@ tor_log_update_sigsafe_err_fds(void)
if (lf->fd == STDERR_FILENO)
found_real_stderr = 1;
/* Avoid duplicates */
if (int_array_contains(fds, n_fds, lf->fd))
/* Avoid duplicates by checking the log module fd against log_fds */
if (int_array_contains(log_fds, n_fds, lf->fd))
fds[n_fds++] = lf->fd;
/* Update log_fds using the log module's fd */
log_fds[n_fds] = lf->fd;
if (lf->needs_close) {
/* File log fds are duplicated, because close_log() closes the log
* module's fd, and tor_log_close_sigsafe_err_fds() closes the err
* module's fd. Both refer to the same file. */
err_fds[n_fds] = dup(lf->fd);
} else {
/* stdio log fds are not closed by the log module.
* tor_log_close_sigsafe_err_fds() closes stdio logs. */
err_fds[n_fds] = lf->fd;
if (!found_real_stderr &&
int_array_contains(fds, n_fds, STDOUT_FILENO)) {
int_array_contains(log_fds, n_fds, STDOUT_FILENO)) {
/* Don't use a virtual stderr when we're also logging to stdout. */
raw_assert(n_fds >= 2); /* Don't tor_assert inside log fns */
fds[0] = fds[--n_fds];
log_fds[0] = log_fds[n_fds];
err_fds[0] = err_fds[n_fds];
tor_log_set_sigsafe_err_fds(fds, n_fds);
tor_log_set_sigsafe_err_fds(err_fds, n_fds);
/** Add to <b>out</b> a copy of every currently configured log file name. Used
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment