X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=src%2Flogging.c;h=3c9dc03f9d15b32bc31396549070b8c30c0e02c1;hb=ea19c978160af32e4fee8001f5308518bcf4fd4c;hp=2c24f2fb14884f0ec2e02aceb31e4d8dba59a11f;hpb=3abad6a6f9ae4cfa65c9f6d5f15208790449eefe;p=osmocom-bb.git diff --git a/src/logging.c b/src/logging.c index 2c24f2f..3c9dc03 100644 --- a/src/logging.c +++ b/src/logging.c @@ -143,29 +143,19 @@ static void _output(struct log_target *target, unsigned int subsys, unsigned int level, char *file, int line, int cont, const char *format, va_list ap) { - char col[30]; - char sub[30]; - char tim[30]; char buf[4096]; - char final[4096]; - - /* prepare the data */ - col[0] = '\0'; - sub[0] = '\0'; - tim[0] = '\0'; - buf[0] = '\0'; + int ret, len = 0, offset = 0, rem = sizeof(buf); /* are we using color */ if (target->use_color) { const char *c = color(subsys); if (c) { - snprintf(col, sizeof(col), "%s", color(subsys)); - col[sizeof(col)-1] = '\0'; + ret = snprintf(buf + offset, rem, "%s", color(subsys)); + if (ret < 0) + goto err; + OSMO_SNPRINTF_RET(ret, rem, offset, len); } } - vsnprintf(buf, sizeof(buf), format, ap); - buf[sizeof(buf)-1] = '\0'; - if (!cont) { if (target->print_timestamp) { char *timestr; @@ -173,17 +163,30 @@ static void _output(struct log_target *target, unsigned int subsys, tm = time(NULL); timestr = ctime(&tm); timestr[strlen(timestr)-1] = '\0'; - snprintf(tim, sizeof(tim), "%s ", timestr); - tim[sizeof(tim)-1] = '\0'; + ret = snprintf(buf + offset, rem, "%s ", timestr); + if (ret < 0) + goto err; + OSMO_SNPRINTF_RET(ret, rem, offset, len); } - snprintf(sub, sizeof(sub), "<%4.4x> %s:%d ", subsys, file, line); - sub[sizeof(sub)-1] = '\0'; + ret = snprintf(buf + offset, rem, "<%4.4x> %s:%d ", + subsys, file, line); + if (ret < 0) + goto err; + OSMO_SNPRINTF_RET(ret, rem, offset, len); } + ret = vsnprintf(buf + offset, rem, format, ap); + if (ret < 0) + goto err; + OSMO_SNPRINTF_RET(ret, rem, offset, len); - snprintf(final, sizeof(final), "%s%s%s%s%s", col, tim, sub, buf, - target->use_color ? "\033[0;m" : ""); - final[sizeof(final)-1] = '\0'; - target->output(target, level, final); + ret = snprintf(buf + offset, rem, "%s", + target->use_color ? "\033[0;m" : ""); + if (ret < 0) + goto err; + OSMO_SNPRINTF_RET(ret, rem, offset, len); +err: + buf[sizeof(buf)-1] = '\0'; + target->output(target, level, buf); } @@ -195,6 +198,7 @@ static void _logp(unsigned int subsys, int level, char *file, int line, llist_for_each_entry(tar, &osmo_log_target_list, entry) { struct log_category *category; int output = 0; + va_list bp; category = &tar->categories[subsys]; /* subsystem is not supposed to be logged */ @@ -218,19 +222,15 @@ static void _logp(unsigned int subsys, int level, char *file, int line, else if (osmo_log_info->filter_fn) output = osmo_log_info->filter_fn(&log_context, tar); + if (!output) + continue; - if (output) { - /* FIXME: copying the va_list is an ugly - * workaround against a bug hidden somewhere in - * _output. If we do not copy here, the first - * call to _output() will corrupt the va_list - * contents, and any further _output() calls - * with the same va_list will segfault */ - va_list bp; - va_copy(bp, ap); - _output(tar, subsys, level, file, line, cont, format, bp); - va_end(bp); - } + /* According to the manpage, vsnprintf leaves the value of ap + * in undefined state. Since _output uses vsnprintf and it may + * be called several times, we have to pass a copy of ap. */ + va_copy(bp, ap); + _output(tar, subsys, level, file, line, cont, format, ap); + va_end(bp); } } @@ -448,11 +448,11 @@ const char *log_vty_command_string(const struct log_info *info) size += strlen(loglevel_strs[i].str) + 1; rem = size; - str = talloc_zero_size(NULL, size); + str = talloc_zero_size(tall_log_ctx, size); if (!str) return NULL; - ret = snprintf(str + offset, rem, "logging level ("); + ret = snprintf(str + offset, rem, "logging level (all|"); if (ret < 0) goto err; OSMO_SNPRINTF_RET(ret, rem, offset, len); @@ -499,6 +499,7 @@ const char *log_vty_command_string(const struct log_info *info) goto err; OSMO_SNPRINTF_RET(ret, rem, offset, len); err: + str[size-1] = '\0'; return str; } @@ -517,8 +518,9 @@ const char *log_vty_command_description(const struct log_info *info) for (i = 0; i < LOGLEVEL_DEFS; i++) size += strlen(loglevel_descriptions[i]) + 1; + size += strlen("Global setting for all subsystems") + 1; rem = size; - str = talloc_zero_size(NULL, size); + str = talloc_zero_size(tall_log_ctx, size); if (!str) return NULL; @@ -528,6 +530,12 @@ const char *log_vty_command_description(const struct log_info *info) goto err; OSMO_SNPRINTF_RET(ret, rem, offset, len); + ret = snprintf(str + offset, rem, + "Global setting for all subsystems\n"); + if (ret < 0) + goto err; + OSMO_SNPRINTF_RET(ret, rem, offset, len); + for (i = 0; i < info->num_cat; i++) { ret = snprintf(str + offset, rem, "%s\n", info->cat[i].description); @@ -543,6 +551,7 @@ const char *log_vty_command_description(const struct log_info *info) OSMO_SNPRINTF_RET(ret, rem, offset, len); } err: + str[size-1] = '\0'; return str; }