X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=daemon.c;h=a4e2f3193730d456ce9908eb55888cdb759154e0;hp=ddfe680cebc63dc1c7af89fde333c665873765eb;hb=HEAD;hpb=2031b9cab9304b02c0372f73eef54d9501277031 diff --git a/daemon.c b/daemon.c index ddfe680c..d8f598be 100644 --- a/daemon.c +++ b/daemon.c @@ -31,6 +31,12 @@ struct daemon { /** Used for colored log messages. */ char log_colors[NUM_LOGLEVELS][COLOR_MAXLEN]; char *old_cwd; + /* + * If these pointers are non-NULL, the functions are called from + * daemon_log() before and after writing each log message. + */ + void (*pre_log_hook)(void); + void (*post_log_hook)(void); }; static struct daemon the_daemon, *me = &the_daemon; @@ -52,24 +58,30 @@ static void daemon_set_default_log_colors(void) } /** - * Set the color for one loglevel. + * Set the color for log messages of the given severity level. * - * \param arg Must be of the form "ll:[fg [bg]] [attr]". + * \param arg Must be of the form "severity:[fg [bg]] [attr]". */ void daemon_set_log_color_or_die(const char *arg) { + unsigned ll; + const char * const sev[] = {SEVERITIES}; char *p = strchr(arg, ':'); - int ret, ll; if (!p) goto err; - ret = get_loglevel_by_name(arg); - if (ret < 0) - goto err; - ll = ret; - p++; - color_parse_or_die(p, me->log_colors[ll]); - return; + for (ll = 0; ll < NUM_LOGLEVELS; ll++) { + const char *name = sev[ll]; + /* + * Parse only the first part of the string so that, for + * example, the argument "info:something_else" is recognized. + * Note that the string comparison is performed + * case-insensitively. + */ + if (strncasecmp(arg, name, strlen(name))) + continue; + return color_parse_or_die(p + 1, me->log_colors[ll]); + } err: PARA_EMERG_LOG("%s: invalid color argument\n", arg); exit(EXIT_FAILURE); @@ -128,16 +140,51 @@ void daemon_set_logfile(const char *logfile_name) } /** - * Suppress log messages with severity lower than the given loglevel. + * Control the verbosity for logging. + * + * This instructs the daemon to not log subsequent messages whose severity is + * lower than the given value. + * + * \param loglevel The new log level. + */ +void daemon_set_loglevel(int loglevel) +{ + assert(loglevel >= 0); + assert(loglevel < NUM_LOGLEVELS); + me->loglevel = loglevel; +} + +/** + * Get the current log level of the daemon. * - * \param loglevel The smallest level that should be logged. + * \return Greater or equal than zero and less than NUM_LOGLEVELS. This + * function never fails. */ -void daemon_set_loglevel(const char *loglevel) +int daemon_get_loglevel(void) { - int ret = get_loglevel_by_name(loglevel); + return me->loglevel; +} - assert(ret >= 0); - me->loglevel = ret; +/** + * Register functions to be called before and after a message is logged. + * + * \param pre_log_hook Called before the message is logged. + * \param post_log_hook Called after the message is logged. + * + * The purpose of this function is to provide a primitive for multi-threaded + * applications to serialize the access to the log facility, preventing + * interleaving log messages. This can be achieved by having the pre-log hook + * acquire a lock which blocks the other threads on the attempt to log a + * message at the same time. The post-log hook is responsible for releasing + * the lock. + * + * If these hooks are unnecessary, for example because the application is + * single-threaded, this function does not need to be called. + */ +void daemon_set_hooks(void (*pre_log_hook)(void), void (*post_log_hook)(void)) +{ + me->pre_log_hook = pre_log_hook; + me->post_log_hook = post_log_hook; } /** @@ -235,9 +282,9 @@ void daemon_close_log(void) } /** - * fopen() the logfile in append mode. + * Open the logfile in append mode. * - * \return Either succeeds or exits. + * This function either succeeds or exits. */ void daemon_open_log_or_die(void) { @@ -409,6 +456,8 @@ __printf_2_3 void daemon_log(int ll, const char* fmt,...) return; fp = me->logfile? me->logfile : stderr; + if (me->pre_log_hook) + me->pre_log_hook(); color = daemon_test_flag(DF_COLOR_LOG)? me->log_colors[ll] : NULL; if (color) fprintf(fp, "%s", color); @@ -441,4 +490,6 @@ __printf_2_3 void daemon_log(int ll, const char* fmt,...) va_end(argp); if (color) fprintf(fp, "%s", COLOR_RESET); + if (me->post_log_hook) + me->post_log_hook(); }