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:
parent
c4cd415ce5
commit
4be48b56f0
2 changed files with 22 additions and 0 deletions
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue