Skip to content

Commit

Permalink
Restore stderr/stdout before calling panic_action (if in foreground m…
Browse files Browse the repository at this point in the history
…ode)

Rename fr_log_t field dest to dst to match the macros
  • Loading branch information
arr2036 committed Apr 4, 2014
1 parent dab5844 commit fd6a28e
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 94 deletions.
12 changes: 12 additions & 0 deletions src/include/libradius.h
Expand Up @@ -758,13 +758,25 @@ void fr_cbuff_rp_insert(fr_cbuff_t *cbuff, void *obj);
void *fr_cbuff_rp_next(fr_cbuff_t *cbuff, TALLOC_CTX *ctx);

/* debug.c */

/** Optional callback passed to fr_fault_setup
*
* Allows optional logic to be run before calling the main fault handler.
*
* If the callback returns < 0, the main fault handler will not be called.
*
* @param signum signal raised.
* @return 0 on success < 0 on failure.
*/
typedef int (*fr_fault_cb)(int signum);
typedef struct fr_bt_marker fr_bt_marker_t;

void fr_debug_break(void);
void backtrace_print(fr_cbuff_t *cbuff, void *obj);
fr_bt_marker_t *fr_backtrace_attach(fr_cbuff_t **cbuff, TALLOC_CTX *obj);
void NEVER_RETURNS fr_fault(int sig);
int fr_fault_setup(char const *cmd, char const *program);
void fr_fault_set_cb(fr_fault_cb cb);

/* rbtree.c */
typedef struct rbtree_t rbtree_t;
Expand Down
6 changes: 5 additions & 1 deletion src/include/log.h
Expand Up @@ -66,7 +66,7 @@ typedef struct fr_log_t {
int colourise; //!< Prefix log messages with VT100 escape codes to change text
//!< colour.
int fd; //!< File descriptor to write messages to.
log_dst_t dest; //!< Log destination.
log_dst_t dst; //!< Log destination.
char *file; //!< Path to log file.
char *debug_file; //!< Path to debug log file.
} fr_log_t;
Expand All @@ -77,6 +77,10 @@ extern FR_NAME_NUMBER const syslog_str2fac[];
extern FR_NAME_NUMBER const log_str2dst[];
extern fr_log_t default_log;

bool radlog_std_restore(void);
bool radlog_std_to_log(fr_log_t *log);
int radlog_init(fr_log_t *log, bool close_std);

int vradlog(log_type_t lvl, char const *fmt, va_list ap)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 0)))
Expand Down
23 changes: 19 additions & 4 deletions src/lib/debug.c
Expand Up @@ -61,6 +61,7 @@ struct fr_bt_marker {
#endif

static char panic_action[512];
static fr_fault_cb panic_cb;
static int fr_debugger_present = -1;

/** Stub callback to see if the SIGTRAP handler is overriden
Expand All @@ -73,12 +74,12 @@ static void _sigtrap_handler(UNUSED int signum)
signal(SIGTRAP, SIG_DFL);
}

/** Break in GDB (if were running under GDB)
/** Break in debugger (if were running under a debugger)
*
* If the server is running under GDB this will raise a SIGTRAP which
* will pause the running process.
* If the server is running under a debugger this will raise a
* SIGTRAP which will pause the running process.
*
* If the server is not running under GDB then this will do nothing.
* If the server is not running under debugger then this will do nothing.
*/
void fr_debug_break(void)
{
Expand Down Expand Up @@ -237,6 +238,11 @@ void NEVER_RETURNS fr_fault(int sig)

fprintf(stderr, "FATAL SIGNAL: %s\n", strsignal(sig));

/*
* Run the callback if one was registered
*/
if (panic_cb && (panic_cb(sig) < 0)) fr_exit_now(1);

/*
* Produce a simple backtrace - They've very basic but at least give us an
* idea of the area of the code we hit the issue in.
Expand Down Expand Up @@ -353,3 +359,12 @@ int fr_fault_setup(char const *cmd, char const *program)
return 0;
}

/** Set a callback to be called before fr_fault()
*
* @param cb to execute. If callback returns < 0
* fr_fault will exit before running panic_action code.
*/
void fr_fault_set_cb(fr_fault_cb cb)
{
panic_cb = cb;
};
2 changes: 1 addition & 1 deletion src/main/command.c
Expand Up @@ -810,7 +810,7 @@ static char debug_log_file_buffer[1024];

static int command_debug_file(rad_listen_t *listener, int argc, char *argv[])
{
if (debug_flag && default_log.dest == L_DST_STDOUT) {
if (debug_flag && default_log.dst == L_DST_STDOUT) {
cprintf(listener, "ERROR: Cannot redirect debug logs to a file when already in debugging mode.\n");
return -1;
}
Expand Down
137 changes: 133 additions & 4 deletions src/main/log.c
Expand Up @@ -36,6 +36,8 @@ RCSID("$Id$")
# include <syslog.h>
#endif

#include <sys/file.h>

/*
* Logging facility names
*/
Expand Down Expand Up @@ -152,11 +154,138 @@ bool log_dates_utc = false;
fr_log_t default_log = {
.colourise = true,
.fd = STDOUT_FILENO,
.dest = L_DST_STDOUT,
.dst = L_DST_STDOUT,
.file = NULL,
.debug_file = NULL,
};

static int stderr_fd = -1; //!< The original unmolested stderr file descriptor
static int stdout_fd = -1; //!< The original unmolested stdout file descriptor

/** Restore the original stderr/stdout file descriptors
*
* Only effective if radlog_init was called with close_stdout = false.
*
* @return true if stdout/stderr have been restored, else false.
*/
bool radlog_std_restore(void)
{
if ((stderr_fd > 0) && (stdout_fd > 0)) {
dup2(stderr_fd, STDOUT_FILENO);
dup2(stdout_fd, STDERR_FILENO);
return true;
}
return false;
}

/** Set stderr/stdout to the current log descriptor.
*
* @param log Logger to manipulate.
* @return true if stdout/stderr have been altered, else false.
*/
bool radlog_std_to_log(fr_log_t *log)
{
if (log->fd > 0) {
dup2(log->fd, STDOUT_FILENO);
dup2(log->fd, STDERR_FILENO);
return true;
}
return false;
}

/** Initialise file descriptors based on logging destination
*
* @param log Logger to manipulate.
* @param close_std Whether we should close stderr and stdout completely, or just redirect them.
* @return 0 on success -1 on failure.
*/
int radlog_init(fr_log_t *log, bool close_std)
{
int devnull;

devnull = open("/dev/null", O_RDWR);
if (devnull < 0) {
fr_strerror_printf("Error opening /dev/null: %s", fr_syserror(errno));
return -1;
}

/*
* Dup the original stdout/stderr file descriptors so
* we can restore them later.
*/
if (!close_std) {
stderr_fd = dup(STDERR_FILENO);
stdout_fd = dup(STDOUT_FILENO);
}

/*
* STDOUT & STDERR go to /dev/null, unless we have "-x",
* then STDOUT & STDERR go to the "-l log" destination.
*
* The complexity here is because "-l log" can go to
* STDOUT or STDERR, too.
*/
if (log->dst == L_DST_STDOUT) {
setlinebuf(stdout);
log->fd = STDOUT_FILENO;

/*
* If we're debugging, allow STDERR to go to
* STDOUT too, for executed programs,
*/
if (debug_flag) {
dup2(STDOUT_FILENO, STDERR_FILENO);
} else {
dup2(devnull, STDERR_FILENO);
}

} else if (log->dst == L_DST_STDERR) {
setlinebuf(stderr);
log->fd = STDERR_FILENO;

/*
* If we're debugging, allow STDOUT to go to
* STDERR too, for executed programs,
*/
if (debug_flag) {
dup2(STDERR_FILENO, STDOUT_FILENO);
} else {
dup2(devnull, STDOUT_FILENO);
}

} else if (log->dst == L_DST_SYSLOG) {
/*
* Discard STDOUT and STDERR no matter what the
* status of debugging. Syslog isn't a file
* descriptor, so we can't use it.
*/
dup2(devnull, STDOUT_FILENO);
dup2(devnull, STDERR_FILENO);

} else if (debug_flag) {
/*
* If we're debugging, allow STDOUT and STDERR to
* go to the log file.
*/
radlog_std_to_log(log);

} else {
/*
* Not debugging, and the log isn't STDOUT or
* STDERR. Ensure that we move both of them to
* /dev/null, so that the calling terminal can
* exit, and the output from executed programs
* doesn't pollute STDOUT / STDERR.
*/
dup2(devnull, STDOUT_FILENO);
dup2(devnull, STDERR_FILENO);
}

close(devnull);

return 0;
}

/*
* Log the message to the logfile. Include the severity and
* a time stamp.
Expand All @@ -182,7 +311,7 @@ int vradlog(log_type_t type, char const *fmt, va_list ap)
* If we don't want any messages, then
* throw them away.
*/
if (default_log.dest == L_DST_NULL) {
if (default_log.dst == L_DST_NULL) {
return 0;
}

Expand All @@ -209,7 +338,7 @@ int vradlog(log_type_t type, char const *fmt, va_list ap)
* Print timestamps for non-debugging, and for high levels
* of debugging.
*/
if (default_log.dest != L_DST_SYSLOG) {
if (default_log.dst != L_DST_SYSLOG) {
if ((debug_flag != 1) && (debug_flag != 2)) {
time_t timeval;

Expand Down Expand Up @@ -262,7 +391,7 @@ int vradlog(log_type_t type, char const *fmt, va_list ap)
buffer[sizeof(buffer) - 1] = '\0';
}

switch (default_log.dest) {
switch (default_log.dst) {

#ifdef HAVE_SYSLOG_H
case L_DST_SYSLOG:
Expand Down
16 changes: 8 additions & 8 deletions src/main/mainconfig.c
Expand Up @@ -690,7 +690,7 @@ static int switch_users(CONF_SECTION *cs)
* specified on the command-line.
*/
if (uid_name || gid_name) {
if ((default_log.dest == L_DST_FILES) &&
if ((default_log.dst == L_DST_FILES) &&
(default_log.fd < 0)) {
default_log.fd = open(mainconfig.log_file,
O_WRONLY | O_APPEND | O_CREAT, 0640);
Expand Down Expand Up @@ -860,7 +860,7 @@ int read_mainconfig(int reload)
* If there was no log destination set on the command line,
* set it now.
*/
if (default_log.dest == L_DST_NULL) {
if (default_log.dst == L_DST_NULL) {
if (cf_section_parse(cs, NULL, serverdest_config) < 0) {
fprintf(stderr, "radiusd: Error: Failed to parse log{} section.\n");
cf_file_free(cs);
Expand All @@ -873,16 +873,16 @@ int read_mainconfig(int reload)
return -1;
}

default_log.dest = fr_str2int(log_str2dst, radlog_dest,
default_log.dst = fr_str2int(log_str2dst, radlog_dest,
L_DST_NUM_DEST);
if (default_log.dest == L_DST_NUM_DEST) {
if (default_log.dst == L_DST_NUM_DEST) {
fprintf(stderr, "radiusd: Error: Unknown log_destination %s\n",
radlog_dest);
cf_file_free(cs);
return -1;
}

if (default_log.dest == L_DST_SYSLOG) {
if (default_log.dst == L_DST_SYSLOG) {
/*
* Make sure syslog_facility isn't NULL
* before using it
Expand All @@ -908,7 +908,7 @@ int read_mainconfig(int reload)
openlog(progname, LOG_PID, mainconfig.syslog_facility);
#endif

} else if (default_log.dest == L_DST_FILES) {
} else if (default_log.dst == L_DST_FILES) {
if (!mainconfig.log_file) {
fprintf(stderr, "radiusd: Error: Specified \"files\" as a log destination, but no log filename was given!\n");
cf_file_free(cs);
Expand All @@ -929,7 +929,7 @@ int read_mainconfig(int reload)
* did switch uid/gid, then the code in switch_users()
* took care of setting the file permissions correctly.
*/
if ((default_log.dest == L_DST_FILES) &&
if ((default_log.dst == L_DST_FILES) &&
(default_log.fd < 0)) {
default_log.fd = open(mainconfig.log_file,
O_WRONLY | O_APPEND | O_CREAT, 0640);
Expand Down Expand Up @@ -1068,7 +1068,7 @@ void hup_logfile(void)
{
int fd, old_fd;

if (default_log.dest != L_DST_FILES) return;
if (default_log.dst != L_DST_FILES) return;

fd = open(mainconfig.log_file,
O_WRONLY | O_APPEND | O_CREAT, 0640);
Expand Down

0 comments on commit fd6a28e

Please sign in to comment.