2009-11-21 Samuel Thibault <samuel.thibault@ens-lyon.org>
[grub2.git] / kern / err.c
blob311130154a896cfaf4f88bca2ee26e01345fc099
1 /* err.c - error handling routines */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <grub/err.h>
21 #include <grub/misc.h>
22 #include <stdarg.h>
24 #define GRUB_MAX_ERRMSG 256
25 #define GRUB_ERROR_STACK_SIZE 10
27 grub_err_t grub_errno;
28 char grub_errmsg[GRUB_MAX_ERRMSG];
30 static struct
32 grub_err_t errno;
33 char errmsg[GRUB_MAX_ERRMSG];
34 } grub_error_stack_items[GRUB_ERROR_STACK_SIZE];
36 static int grub_error_stack_pos;
37 static int grub_error_stack_assert;
39 grub_err_t
40 grub_error (grub_err_t n, const char *fmt, ...)
42 va_list ap;
44 grub_errno = n;
46 va_start (ap, fmt);
47 grub_vsprintf (grub_errmsg, fmt, ap);
48 va_end (ap);
50 return n;
53 void
54 grub_fatal (const char *fmt, ...)
56 va_list ap;
58 va_start (ap, fmt);
59 grub_vprintf (fmt, ap);
60 va_end (ap);
62 grub_abort ();
65 void
66 grub_error_push (void)
68 /* Only add items to stack, if there is enough room. */
69 if (grub_error_stack_pos < GRUB_ERROR_STACK_SIZE)
71 /* Copy active error message to stack. */
72 grub_error_stack_items[grub_error_stack_pos].errno = grub_errno;
73 grub_memcpy (grub_error_stack_items[grub_error_stack_pos].errmsg,
74 grub_errmsg,
75 sizeof (grub_errmsg));
77 /* Advance to next error stack position. */
78 grub_error_stack_pos++;
80 else
82 /* There is no room for new error message. Discard new error message
83 and mark error stack assertion flag. */
84 grub_error_stack_assert = 1;
87 /* Allow further operation of other components by resetting
88 active errno to GRUB_ERR_NONE. */
89 grub_errno = GRUB_ERR_NONE;
92 int
93 grub_error_pop (void)
95 if (grub_error_stack_pos > 0)
97 /* Pop error message from error stack to current active error. */
98 grub_error_stack_pos--;
100 grub_errno = grub_error_stack_items[grub_error_stack_pos].errno;
101 grub_memcpy (grub_errmsg,
102 grub_error_stack_items[grub_error_stack_pos].errmsg,
103 sizeof (grub_errmsg));
105 return 1;
107 else
109 /* There is no more items on error stack, reset to no error state. */
110 grub_errno = GRUB_ERR_NONE;
112 return 0;
116 void
117 grub_print_error (void)
119 /* Print error messages in reverse order. First print active error message
120 and then empty error stack. */
123 if (grub_errno != GRUB_ERR_NONE)
124 grub_err_printf ("error: %s\n", grub_errmsg);
126 while (grub_error_pop ());
128 /* If there was an assert while using error stack, report about it. */
129 if (grub_error_stack_assert)
131 grub_err_printf ("assert: error stack overflow detected!\n");
132 grub_error_stack_assert = 0;