diff options
Diffstat (limited to 'common/console_common.c')
-rw-r--r-- | common/console_common.c | 149 |
1 files changed, 91 insertions, 58 deletions
diff --git a/common/console_common.c b/common/console_common.c index 6916f651e5..0113a64138 100644 --- a/common/console_common.c +++ b/common/console_common.c @@ -1,57 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * based on code: * * (C) Copyright 2000 Paolo Scaffardi, AIRVENT SAM s.p.a - * RIMINI(ITALY), arsenio@tin.it - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <common.h> #include <fs.h> #include <errno.h> #include <console.h> #include <init.h> +#include <string.h> #include <environment.h> #include <globalvar.h> #include <magicvar.h> +#include <memory.h> +#include <of.h> #include <password.h> #include <clock.h> #include <malloc.h> #include <linux/pstore.h> -#include <asm-generic/div64.h> +#include <linux/math64.h> +#include <linux/sizes.h> +#include <linux/overflow.h> #ifndef CONFIG_CONSOLE_NONE static const char *colored_log_level[] = { - [MSG_EMERG] = "\033[31mEMERG:\033[0m ", /* red */ - [MSG_ALERT] = "\033[31mALERT:\033[0m ", /* red */ - [MSG_CRIT] = "\033[31mCRITICAL:\033[0m ", /* red */ - [MSG_ERR] = "\033[31mERROR:\033[0m ", /* red */ - [MSG_WARNING] = "\033[33mWARNING:\033[0m ", /* yellow */ - [MSG_NOTICE] = "\033[34mNOTICE:\033[0m ", /* blue */ + [MSG_EMERG] = "\033[1;31mEMERG:\033[0m ", /* red */ + [MSG_ALERT] = "\033[1;31mALERT:\033[0m ", /* red */ + [MSG_CRIT] = "\033[1;31mCRITICAL:\033[0m ", /* red */ + [MSG_ERR] = "\033[1;31mERROR:\033[0m ", /* red */ + [MSG_WARNING] = "\033[1;33mWARNING:\033[0m ", /* yellow */ + [MSG_NOTICE] = "\033[1;34mNOTICE:\033[0m ", /* blue */ }; int barebox_loglevel = CONFIG_DEFAULT_LOGLEVEL; LIST_HEAD(barebox_logbuf); static int barebox_logbuf_num_messages; -static int barebox_log_max_messages = 1000; +static int barebox_log_max_messages; static void log_del(struct log_entry *log) { - free(log->msg); list_del(&log->list); free(log); barebox_logbuf_num_messages--; @@ -63,7 +54,7 @@ static void log_del(struct log_entry *log) * @limit: The maximum messages left in the buffer after * calling this function. * - * This function deletes all messages in the logbuf exeeding + * This function deletes all messages in the logbuf exceeding * the limit. */ void log_clean(unsigned int limit) @@ -80,7 +71,7 @@ void log_clean(unsigned int limit) } } -static void print_colored_log_level(const int level) +static void print_colored_log_level(unsigned int ch, const int level) { if (!console_allow_color()) return; @@ -89,7 +80,7 @@ static void print_colored_log_level(const int level) if (!colored_log_level[level]) return; - puts(colored_log_level[level]); + console_puts(ch, colored_log_level[level]); } static void pr_puts(int level, const char *str) @@ -101,15 +92,14 @@ static void pr_puts(int level, const char *str) log_clean(barebox_log_max_messages - 1); if (barebox_log_max_messages >= 0) { - log = malloc(sizeof(*log)); + int msglen; + + msglen = strlen(str); + log = malloc(struct_size(log, msg, msglen + 1)); if (!log) goto nolog; - log->msg = strdup(str); - if (!log->msg) { - free(log); - goto nolog; - } + memcpy(log->msg, str, msglen + 1); log->timestamp = get_time_ns(); log->level = level; @@ -124,8 +114,8 @@ nolog: if (level > barebox_loglevel) return; - print_colored_log_level(level); - puts(str); + print_colored_log_level(CONSOLE_STDERR, level); + console_puts(CONSOLE_STDERR, str); } int pr_print(int level, const char *fmt, ...) @@ -138,7 +128,7 @@ int pr_print(int level, const char *fmt, ...) return 0; va_start(args, fmt); - i = vsprintf(printbuffer, fmt, args); + i = vsnprintf(printbuffer, sizeof(printbuffer), fmt, args); va_end(args); pr_puts(level, printbuffer); @@ -146,23 +136,24 @@ int pr_print(int level, const char *fmt, ...) return i; } -int dev_printf(int level, const struct device_d *dev, const char *format, ...) +int dev_printf(int level, const struct device *dev, const char *format, ...) { va_list args; int ret = 0; char printbuffer[CFG_PBSIZE]; + size_t size = sizeof(printbuffer); if (!IS_ENABLED(CONFIG_LOGBUF) && level > barebox_loglevel) return 0; - if (dev->driver && dev->driver->name) - ret += sprintf(printbuffer, "%s ", dev->driver->name); + if (dev && dev->driver && dev->driver->name) + ret += snprintf(printbuffer, size, "%s ", dev->driver->name); - ret += sprintf(printbuffer + ret, "%s: ", dev_name(dev)); + ret += snprintf(printbuffer + ret, size - ret, "%s: ", dev_name(dev)); va_start(args, format); - ret += vsprintf(printbuffer + ret, format, args); + ret += vsnprintf(printbuffer + ret, size - ret, format, args); va_end(args); @@ -184,50 +175,73 @@ bool console_allow_color(void) static int console_common_init(void) { - if (IS_ENABLED(CONFIG_LOGBUF)) + if (IS_ENABLED(CONFIG_LOGBUF)) { + barebox_log_max_messages + = clamp(mem_malloc_size() / SZ_32K, 1000UL, 100000UL); globalvar_add_simple_int("log_max_messages", &barebox_log_max_messages, "%d"); + } globalvar_add_simple_bool("allow_color", &__console_allow_color); return globalvar_add_simple_int("loglevel", &barebox_loglevel, "%d"); } -device_initcall(console_common_init); +core_initcall(console_common_init); + +int log_writefile(const char *filepath) +{ + int ret = 0, nbytes = 0, fd = -1; + struct log_entry *log; + + fd = open(filepath, O_WRONLY | O_CREAT | O_TRUNC); + if (fd < 0) + return -errno; + + list_for_each_entry(log, &barebox_logbuf, list) { + ret = dputs(fd, log->msg); + if (ret < 0) + break; + nbytes += ret; + } + + close(fd); + return ret < 0 ? ret : nbytes; +} -void log_print(unsigned flags, unsigned levels) +int log_print(unsigned flags, unsigned levels) { struct log_entry *log; unsigned long last = 0; list_for_each_entry(log, &barebox_logbuf, list) { - uint64_t diff = log->timestamp - time_beginning; - unsigned long difful; + uint64_t time_ns = log->timestamp; + unsigned long time; if (levels && !(levels & (1 << log->level))) continue; + if (ctrlc()) + return -EINTR; if (!(flags & (BAREBOX_LOG_PRINT_RAW | BAREBOX_LOG_PRINT_TIME | BAREBOX_LOG_DIFF_TIME))) - print_colored_log_level(log->level); + print_colored_log_level(CONSOLE_STDOUT, log->level); if (flags & BAREBOX_LOG_PRINT_RAW) printf("<%i>", log->level); - do_div(diff, 1000); - difful = diff; - - if (!log->timestamp) - difful = 0; + /* convert ns to us */ + do_div(time_ns, 1000); + time = time_ns; if (flags & (BAREBOX_LOG_PRINT_TIME | BAREBOX_LOG_DIFF_TIME)) printf("["); if (flags & BAREBOX_LOG_PRINT_TIME) - printf("%10luus", difful); + printf("%10luus", time); if (flags & BAREBOX_LOG_DIFF_TIME) { - printf(" < %10luus", difful - last); - last = difful; + printf(" < %10luus", time - last); + last = time; } if (flags & (BAREBOX_LOG_PRINT_TIME | BAREBOX_LOG_DIFF_TIME)) @@ -235,6 +249,8 @@ void log_print(unsigned flags, unsigned levels) printf("%s", log->msg); } + + return 0; } int printf(const char *fmt, ...) @@ -249,7 +265,7 @@ int printf(const char *fmt, ...) * For this to work, printbuffer must be larger than * anything we ever want to print. */ - i = vsprintf (printbuffer, fmt, args); + i = vsnprintf(printbuffer, sizeof(printbuffer), fmt, args); va_end(args); /* Print the string */ @@ -268,7 +284,7 @@ int vprintf(const char *fmt, va_list args) * For this to work, printbuffer must be larger than * anything we ever want to print. */ - i = vsprintf(printbuffer, fmt, args); + i = vsnprintf(printbuffer, sizeof(printbuffer), fmt, args); /* Print the string */ puts(printbuffer); @@ -277,7 +293,7 @@ int vprintf(const char *fmt, va_list args) } EXPORT_SYMBOL(vprintf); -struct console_device *console_get_by_dev(struct device_d *dev) +struct console_device *console_get_by_dev(struct device *dev) { struct console_device *cdev; @@ -326,6 +342,23 @@ struct console_device *console_get_first_active(void) } EXPORT_SYMBOL(console_get_first_active); +struct console_device *of_console_get_by_alias(const char *alias) +{ + struct device_node *node; + struct device *dev; + + node = of_find_node_by_alias(NULL, alias); + if (!node) + return NULL; + + dev = of_find_device_by_node(node); + if (!dev) + return NULL; + + return console_get_by_dev(dev); +} +EXPORT_SYMBOL(of_console_get_by_alias); + #endif /* !CONFIG_CONSOLE_NONE */ int dprintf(int file, const char *fmt, ...) @@ -339,7 +372,7 @@ int dprintf(int file, const char *fmt, ...) * For this to work, printbuffer must be larger than * anything we ever want to print. */ - vsprintf(printbuffer, fmt, args); + vsnprintf(printbuffer, sizeof(printbuffer), fmt, args); va_end(args); /* Print the string */ |