From 6a1241038441cb2be4319dfad69b2de7305e3bb8 Mon Sep 17 00:00:00 2001 From: chaac Date: Fri, 23 Dec 2005 22:59:12 +0000 Subject: [PATCH] 2005-12-24 Vesa Jaaskelainen * kern/err.c (grub_error_push): Added new function to support error stacks. (grub_error_pop): Likewise. (grub_error_stack_items): New local variable to support error stacks. (grub_error_stack_pos): Likewise. (grub_error_stack_assert): Likewise. (GRUB_ERROR_STACK_SIZE): Added new define to configure maximum error stack depth. (grub_print_error): Added support to print errors from error stack. * include/grub/err.h (grub_error_push): Added function prototype. (grub_error_pop): Likewise. --- ChangeLog | 15 +++++++++ include/grub/err.h | 4 ++- kern/err.c | 82 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 96 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8609ba9c1..c491f7569 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2005-12-24 Vesa Jaaskelainen + + * kern/err.c (grub_error_push): Added new function to support error + stacks. + (grub_error_pop): Likewise. + (grub_error_stack_items): New local variable to support error stacks. + (grub_error_stack_pos): Likewise. + (grub_error_stack_assert): Likewise. + (GRUB_ERROR_STACK_SIZE): Added new define to configure maximum error + stack depth. + (grub_print_error): Added support to print errors from error stack. + + * include/grub/err.h (grub_error_push): Added function prototype. + (grub_error_pop): Likewise. + 2005-12-09 Hollis Blanchard * configure.ac: Accept `powerpc64' as host_cpu. diff --git a/include/grub/err.h b/include/grub/err.h index 3ef858225..d4013be6c 100644 --- a/include/grub/err.h +++ b/include/grub/err.h @@ -1,7 +1,7 @@ /* err.h - error numbers and prototypes */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2004 Free Software Foundation, Inc. + * Copyright (C) 2002-2005 Free Software Foundation, Inc. * * GRUB is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,6 +60,8 @@ extern char EXPORT_VAR(grub_errmsg)[]; grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...); void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn)); +void EXPORT_FUNC(grub_error_push) (void); +int EXPORT_FUNC(grub_error_pop) (void); void EXPORT_FUNC(grub_print_error) (void); #endif /* ! GRUB_ERR_HEADER */ diff --git a/kern/err.c b/kern/err.c index df0df26e5..33c376174 100644 --- a/kern/err.c +++ b/kern/err.c @@ -1,7 +1,7 @@ /* err.c - error handling routines */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002 Free Software Foundation, Inc. + * Copyright (C) 2002,2005 Free Software Foundation, Inc. * * GRUB is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,11 +22,21 @@ #include #include -#define GRUB_MAX_ERRMSG 256 +#define GRUB_MAX_ERRMSG 256 +#define GRUB_ERROR_STACK_SIZE 10 grub_err_t grub_errno; char grub_errmsg[GRUB_MAX_ERRMSG]; +static struct +{ + grub_err_t errno; + char errmsg[GRUB_MAX_ERRMSG]; +} grub_error_stack_items[GRUB_ERROR_STACK_SIZE]; + +static int grub_error_stack_pos; +static int grub_error_stack_assert; + grub_err_t grub_error (grub_err_t n, const char *fmt, ...) { @@ -53,9 +63,73 @@ grub_fatal (const char *fmt, ...) grub_stop (); } +void +grub_error_push (void) +{ + /* Only add items to stack, if there is enough room. */ + if (grub_error_stack_pos < GRUB_ERROR_STACK_SIZE) + { + /* Copy active error message to stack. */ + grub_error_stack_items[grub_error_stack_pos].errno = grub_errno; + grub_memcpy (grub_error_stack_items[grub_error_stack_pos].errmsg, + grub_errmsg, + sizeof (grub_errmsg)); + + /* Advance to next error stack position. */ + grub_error_stack_pos++; + } + else + { + /* There is no room for new error message. Discard new error message + and mark error stack assertion flag. */ + grub_error_stack_assert = 1; + } + + /* Allow further operation of other components by resetting + active errno to GRUB_ERR_NONE. */ + grub_errno = GRUB_ERR_NONE; +} + +int +grub_error_pop (void) +{ + if (grub_error_stack_pos > 0) + { + /* Pop error message from error stack to current active error. */ + grub_error_stack_pos--; + + grub_errno = grub_error_stack_items[grub_error_stack_pos].errno; + grub_memcpy (grub_errmsg, + grub_error_stack_items[grub_error_stack_pos].errmsg, + sizeof (grub_errmsg)); + + return 1; + } + else + { + /* There is no more items on error stack, reset to no error state. */ + grub_errno = GRUB_ERR_NONE; + + return 0; + } +} + void grub_print_error (void) { - if (grub_errno != GRUB_ERR_NONE) - grub_printf ("error: %s\n", grub_errmsg); + /* Print error messages in reverse order. First print active error message + and then empty error stack. */ + do + { + if (grub_errno != GRUB_ERR_NONE) + grub_printf ("error: %s\n", grub_errmsg); + } + while (grub_error_pop ()); + + /* If there was an assert while using error stack, report about it. */ + if (grub_error_stack_assert) + { + grub_printf ("assert: error stack overflow detected!\n"); + grub_error_stack_assert = 0; + } }