err.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /* err.c - error handling routines */
  2. /*
  3. * GRUB -- GRand Unified Bootloader
  4. * Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc.
  5. *
  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.
  10. *
  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.
  15. *
  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/>.
  18. */
  19. #include <grub/err.h>
  20. #include <grub/misc.h>
  21. #include <stdarg.h>
  22. #include <grub/i18n.h>
  23. GRUB_EXPORT(grub_errno);
  24. GRUB_EXPORT(grub_errmsg);
  25. GRUB_EXPORT(grub_error);
  26. GRUB_EXPORT(grub_fatal);
  27. GRUB_EXPORT(grub_error_push);
  28. GRUB_EXPORT(grub_error_pop);
  29. GRUB_EXPORT(grub_print_error);
  30. GRUB_EXPORT(grub_err_printf);
  31. #define GRUB_MAX_ERRMSG 256
  32. #define GRUB_ERROR_STACK_SIZE 10
  33. grub_err_t grub_errno;
  34. char grub_errmsg[GRUB_MAX_ERRMSG];
  35. static struct
  36. {
  37. grub_err_t errno;
  38. char errmsg[GRUB_MAX_ERRMSG];
  39. } grub_error_stack_items[GRUB_ERROR_STACK_SIZE];
  40. static int grub_error_stack_pos;
  41. static int grub_error_stack_assert;
  42. grub_err_t
  43. grub_error (grub_err_t n, const char *fmt, ...)
  44. {
  45. va_list ap;
  46. grub_errno = n;
  47. va_start (ap, fmt);
  48. grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), _(fmt), ap);
  49. va_end (ap);
  50. return n;
  51. }
  52. void
  53. grub_fatal (const char *fmt, ...)
  54. {
  55. va_list ap;
  56. va_start (ap, fmt);
  57. grub_vprintf (_(fmt), ap);
  58. va_end (ap);
  59. grub_abort ();
  60. }
  61. void
  62. grub_error_push (void)
  63. {
  64. /* Only add items to stack, if there is enough room. */
  65. if (grub_error_stack_pos < GRUB_ERROR_STACK_SIZE)
  66. {
  67. /* Copy active error message to stack. */
  68. grub_error_stack_items[grub_error_stack_pos].errno = grub_errno;
  69. grub_memcpy (grub_error_stack_items[grub_error_stack_pos].errmsg,
  70. grub_errmsg,
  71. sizeof (grub_errmsg));
  72. /* Advance to next error stack position. */
  73. grub_error_stack_pos++;
  74. }
  75. else
  76. {
  77. /* There is no room for new error message. Discard new error message
  78. and mark error stack assertion flag. */
  79. grub_error_stack_assert = 1;
  80. }
  81. /* Allow further operation of other components by resetting
  82. active errno to GRUB_ERR_NONE. */
  83. grub_errno = GRUB_ERR_NONE;
  84. }
  85. int
  86. grub_error_pop (void)
  87. {
  88. if (grub_error_stack_pos > 0)
  89. {
  90. /* Pop error message from error stack to current active error. */
  91. grub_error_stack_pos--;
  92. grub_errno = grub_error_stack_items[grub_error_stack_pos].errno;
  93. grub_memcpy (grub_errmsg,
  94. grub_error_stack_items[grub_error_stack_pos].errmsg,
  95. sizeof (grub_errmsg));
  96. return 1;
  97. }
  98. else
  99. {
  100. /* There is no more items on error stack, reset to no error state. */
  101. grub_errno = GRUB_ERR_NONE;
  102. return 0;
  103. }
  104. }
  105. void
  106. grub_print_error (void)
  107. {
  108. /* Print error messages in reverse order. First print active error message
  109. and then empty error stack. */
  110. do
  111. {
  112. if (grub_errno != GRUB_ERR_NONE)
  113. grub_err_printf (_("error: %s.\n"), grub_errmsg);
  114. }
  115. while (grub_error_pop ());
  116. /* If there was an assert while using error stack, report about it. */
  117. if (grub_error_stack_assert)
  118. {
  119. grub_err_printf ("assert: error stack overflow detected!\n");
  120. grub_error_stack_assert = 0;
  121. }
  122. }