From 2b85b3865f9274c9c40cc6ebf7227fbcd49a9479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sun, 4 Nov 2012 23:57:38 +0100 Subject: [PATCH] Add uc_log_delete_destination. Make a copy of ident for syslog destination --- src/ucore_logging.c | 63 ++++++++++++++++++++++++++++++++++++++++++--- src/ucore_logging.h | 14 ++++++++++ 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/src/ucore_logging.c b/src/ucore_logging.c index 0e04d26..87e25b2 100644 --- a/src/ucore_logging.c +++ b/src/ucore_logging.c @@ -17,7 +17,7 @@ struct uc_log_destination { union { //for syslog struct { - const char *ident; + char *ident; int facility; } syslog; //for stderr and files @@ -106,14 +106,22 @@ struct uc_log_destination *uc_log_new_stderr(int log_level, int log_location) struct uc_log_destination *uc_log_new_syslog(const char *ident, int facility, int log_level, int log_location) { struct uc_log_destination *dest = calloc(1, sizeof *dest); + char *id; if(dest == NULL) return NULL; + //copy the ident - though it's unused inside the struct for now + id = strdup(ident); + if(id == NULL) { + free(dest); + return NULL; + } + openlog(ident, LOG_NDELAY | LOG_PID, facility); dest->dest_type = UC_LDEST_SYSLOG; - dest->type.syslog.ident = ident; + dest->type.syslog.ident = id; dest->type.syslog.facility = facility; dest->log_level = log_level;; dest->log_location = log_location; @@ -172,11 +180,60 @@ void uc_log_add_destination(struct uc_log_destination *dest) pthread_mutex_unlock(&log_lock); } +static inline void uc_log_remove_dest_unlocked(struct uc_log_destination *dest) +{ + struct uc_log_destination *it; + + //check that it's not already removed + SLIST_FOREACH(it, &destinations, entry) { + if(it == dest); + break; + } + + if(it != NULL) { + SLIST_REMOVE(&destinations, dest, uc_log_destination, entry); + } +} + void uc_log_remove_destination(struct uc_log_destination *dest) { + pthread_mutex_lock(&log_lock); - SLIST_REMOVE(&destinations, dest, uc_log_destination, entry); + uc_log_remove_dest_unlocked(dest); + + pthread_mutex_unlock(&log_lock); +} + +void uc_log_delete_destination(struct uc_log_destination *dest) +{ + if(dest == NULL) + return; + + pthread_mutex_lock(&log_lock); + + //remove it + uc_log_remove_dest_unlocked(dest); + + //clean up, according to the type + switch(dest->dest_type) { + case UC_LDEST_SYSLOG: + free(dest->type.syslog.ident); + closelog(); + break; + case UC_LDEST_STDERR: //nothing to do + break; + case UC_LDEST_FILE: + if(dest->type.file.file != NULL) { + fclose(dest->type.file.file); + dest->type.file.file = NULL; + } + + free(dest->type.file.file_name); + break; + } + + free(dest); pthread_mutex_unlock(&log_lock); } diff --git a/src/ucore_logging.h b/src/ucore_logging.h index 5fb3da5..5f19efb 100644 --- a/src/ucore_logging.h +++ b/src/ucore_logging.h @@ -111,11 +111,25 @@ struct uc_log_destination *uc_log_new_file(const char *filename, int log_level, void uc_log_add_destination(struct uc_log_destination *dest); /** Remove a log destination. + * Note that this does not free the destination, it can be readded later. + * For file destination, the log file is NOT closed. * * @param dest The uc_log_destination to remove. */ void uc_log_remove_destination(struct uc_log_destination *dest); +/** Remove and free a destination. + * This frees the memory allocated to the destination. For + * UC_LDEST_FILE the log file is closed. + * + * If the destination is not already removed, it will be removed first, + * there's no need to call uc_log_remove_destination first. + * The destination cannot be used again after this function has been called. + * + * @param dest The destination to delete. + */ +void uc_log_delete_destination(struct uc_log_destination *dest); + /** Change the log level of a module. * * @param module The module to change, matched against the id member of a struct uc_log_module