8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 10:00:38 +01:00

Allow to redirect server's stdout and stderr to file (#143)

Before these changes guardian and server binary closed
stdin/stdout/stderr/... and server can reuse those
descriptors when opening files or using shmem for
example. So some stray stdout can introduce
unwanted data or even crash server. Server do not
emit any stdout/stderr in release build but
UDRs or external libraries can print to stdout.

After these changes stdout/stderr will be kept opened
and user have options to redirect it to /dev/null (by default)
or other file by choise or just allow server to print.

New config option OutputRedirectionFile was introduced to
allow user control server behavior.
This commit is contained in:
Artyom Smirnov 2018-03-21 14:47:20 +03:00 committed by Alexander Peshkov
parent 1dc40bee49
commit 21b42b2e8f
5 changed files with 64 additions and 3 deletions

View File

@ -811,6 +811,17 @@
#
#EventMemSize = 64K
# ----------------------------
#
# File to redirect stdout and stderr output of server
#
# Default '/dev/null' for *nix and 'nul' for Windows
# Empty value or '-' keeps stdout and stderr as is.
#
# Type: string
#
#OutputRedirectionFile = /dev/null
# ===========================
# Engine Settings

View File

@ -202,7 +202,16 @@ const Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] =
{TYPE_BOOLEAN, "AllowEncryptedSecurityDatabase", (ConfigValue) false},
{TYPE_INTEGER, "StatementTimeout", (ConfigValue) 0},
{TYPE_INTEGER, "ConnectionIdleTimeout", (ConfigValue) 0},
{TYPE_INTEGER, "ClientBatchBuffer", (ConfigValue) (128 * 1024)}
{TYPE_INTEGER, "ClientBatchBuffer", (ConfigValue) (128 * 1024)},
#ifdef DEV_BUILD
{TYPE_STRING, "OutputRedirectionFile", (ConfigValue) "-"},
#else
#ifdef WIN_NT
{TYPE_STRING, "OutputRedirectionFile", (ConfigValue) "nul"},
#else
{TYPE_STRING, "OutputRedirectionFile", (ConfigValue) "/dev/null"}
#endif
#endif
};
/******************************************************************************
@ -839,3 +848,8 @@ unsigned int Config::getClientBatchBuffer() const
return get<unsigned int>(KEY_CLIENT_BATCH_BUFFER);
}
const char* Config::getOutputRedirectionFile()
{
const char* file = (const char*) (getDefaultConfig()->values[KEY_OUTPUT_REDIRECTION_FILE]);
return file;
}

View File

@ -146,6 +146,7 @@ public:
KEY_STMT_TIMEOUT,
KEY_CONN_IDLE_TIMEOUT,
KEY_CLIENT_BATCH_BUFFER,
KEY_OUTPUT_REDIRECTION_FILE,
MAX_CONFIG_KEY // keep it last
};
@ -362,6 +363,8 @@ public:
unsigned int getConnIdleTimeout() const;
unsigned int getClientBatchBuffer() const;
static const char* getOutputRedirectionFile();
};
// Implementation of interface to access master configuration file

View File

@ -345,8 +345,10 @@ int CLIB_ROUTINE main( int argc, char** argv)
if (!(debug || classic))
{
//Keep stdout and stderr openened always. We decide allow output
//from binary or redirect it according to config
int mask = 0; // FD_ZERO(&mask);
mask |= 1 << 2; // FD_SET(2, &mask);
mask |= (1 << 1 | 1 << 2); // FD_SET(1, &mask); FD_SET(2, &mask);
divorce_terminal(mask);
}
@ -357,6 +359,32 @@ int CLIB_ROUTINE main( int argc, char** argv)
exit(STARTUP_ERROR);
}
if (!debug)
{
const char* redirection_file = Config::getOutputRedirectionFile();
if (redirection_file && strcmp(redirection_file, "-") != 0)
{
int f = open(redirection_file, O_CREAT|O_APPEND|O_WRONLY, 0644);
if (f >= 0)
{
int stdout_no = fileno(stdout);
int stderr_no = fileno(stderr);
if (f != stdout_no)
dup2(f, stdout_no);
if (f != stderr_no)
dup2(f, stderr_no);
if (f != stdout_no && f != stderr_no)
close(f);
}
else
{
gds__log("Unable to open file %s for output redirection", redirection_file);
}
}
}
if (super || standaloneClassic)
{
try

View File

@ -167,7 +167,12 @@ int CLIB_ROUTINE main( int argc, char **argv)
if (daemon && fork()) {
exit(0);
}
divorce_terminal(0);
//Keep stdout and stderr opened and let server emit output
//or redirect stdout/stderr to /dev/null or file by user choice
int mask = 0; // FD_ZERO(&mask);
mask |= (1 << 1 | 1 << 2); // FD_SET(1, &mask); FD_SET(2, &mask);
divorce_terminal(mask);
time_t timer = 0;