LogRedirect: added redoRedirect()

The new call is meant to be used after forking: in such a situation,
redirected stdout/stderr output can be read by both the parent and the
child, which leads to a race condition and makes it non-deterministic
where that output will be handled. redoRedirect() closes the child's
connection to the parent's redirection and sets up its own instead.
This commit is contained in:
Patrick Ohly 2011-02-11 11:19:53 +01:00
parent c4cd415ce5
commit 4be48b56f0
2 changed files with 22 additions and 0 deletions

View file

@ -172,6 +172,21 @@ LogRedirect::~LogRedirect() throw()
}
}
void LogRedirect::redoRedirect() throw()
{
bool doStdout = m_stdout.m_copy >= 0;
bool doStderr = m_stderr.m_copy >= 0;
if (doStdout) {
restore(m_stdout);
redirect(STDOUT_FILENO, m_stdout);
}
if (doStderr) {
restore(m_stderr);
redirect(STDERR_FILENO, m_stderr);
}
}
void LogRedirect::restore() throw()
{
if (m_processing) {

View file

@ -143,6 +143,13 @@ class LogRedirect : public LoggerStdout
LogRedirect(bool both = true, const char *filename = NULL) throw();
~LogRedirect() throw();
/**
* re-initialize redirection after a fork:
* - closes inherited file descriptors, except for the original output file descriptor
* - sets up new sockets
*/
void redoRedirect() throw();
/**
* Meant to be used for redirecting output of a specific command
* via fork()/exec(). Prepares reliable streams, as determined by