PageRenderTime 133ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 1ms

/src/bin/bash/error.c

http://github.com/Barrett17/Haiku-services-branch
C | 454 lines | 322 code | 89 blank | 43 comment | 31 complexity | 3a9c5638308b138f0c5c58142226dd69 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, LGPL-2.0, LGPL-2.1, BSD-2-Clause, ISC, Apache-2.0, AGPL-1.0, MIT, MPL-2.0-no-copyleft-exception, Unlicense, BSD-3-Clause, LGPL-3.0
  1. /* error.c -- Functions for handling errors. */
  2. /* Copyright (C) 1993-2009 Free Software Foundation, Inc.
  3. This file is part of GNU Bash, the Bourne Again SHell.
  4. Bash is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. Bash is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with Bash. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include "config.h"
  16. #include "bashtypes.h"
  17. #include <fcntl.h>
  18. #if defined (HAVE_UNISTD_H)
  19. # include <unistd.h>
  20. #endif
  21. #if defined (PREFER_STDARG)
  22. # include <stdarg.h>
  23. #else
  24. # include <varargs.h>
  25. #endif
  26. #include <stdio.h>
  27. #include <errno.h>
  28. #if !defined (errno)
  29. extern int errno;
  30. #endif /* !errno */
  31. #include "bashansi.h"
  32. #include "bashintl.h"
  33. #include "shell.h"
  34. #include "flags.h"
  35. #include "input.h"
  36. #if defined (HISTORY)
  37. # include "bashhist.h"
  38. #endif
  39. extern int executing_line_number __P((void));
  40. extern char *shell_name;
  41. #if defined (JOB_CONTROL)
  42. extern pid_t shell_pgrp;
  43. extern int give_terminal_to __P((pid_t, int));
  44. #endif /* JOB_CONTROL */
  45. #if defined (ARRAY_VARS)
  46. extern const char * const bash_badsub_errmsg;
  47. #endif
  48. static void error_prolog __P((int));
  49. /* The current maintainer of the shell. You change this in the
  50. Makefile. */
  51. #if !defined (MAINTAINER)
  52. #define MAINTAINER "bash-maintainers@gnu.org"
  53. #endif
  54. const char * const the_current_maintainer = MAINTAINER;
  55. int gnu_error_format = 0;
  56. static void
  57. error_prolog (print_lineno)
  58. int print_lineno;
  59. {
  60. char *ename;
  61. int line;
  62. ename = get_name_for_error ();
  63. line = (print_lineno && interactive_shell == 0) ? executing_line_number () : -1;
  64. if (line > 0)
  65. fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), line);
  66. else
  67. fprintf (stderr, "%s: ", ename);
  68. }
  69. /* Return the name of the shell or the shell script for error reporting. */
  70. char *
  71. get_name_for_error ()
  72. {
  73. char *name;
  74. #if defined (ARRAY_VARS)
  75. SHELL_VAR *bash_source_v;
  76. ARRAY *bash_source_a;
  77. #endif
  78. name = (char *)NULL;
  79. if (interactive_shell == 0)
  80. {
  81. #if defined (ARRAY_VARS)
  82. bash_source_v = find_variable ("BASH_SOURCE");
  83. if (bash_source_v && array_p (bash_source_v) &&
  84. (bash_source_a = array_cell (bash_source_v)))
  85. name = array_reference (bash_source_a, 0);
  86. if (name == 0 || *name == '\0') /* XXX - was just name == 0 */
  87. #endif
  88. name = dollar_vars[0];
  89. }
  90. if (name == 0 && shell_name && *shell_name)
  91. name = base_pathname (shell_name);
  92. if (name == 0)
  93. #if defined (PROGRAM)
  94. name = PROGRAM;
  95. #else
  96. name = "bash";
  97. #endif
  98. return (name);
  99. }
  100. /* Report an error having to do with FILENAME. This does not use
  101. sys_error so the filename is not interpreted as a printf-style
  102. format string. */
  103. void
  104. file_error (filename)
  105. const char *filename;
  106. {
  107. report_error ("%s: %s", filename, strerror (errno));
  108. }
  109. void
  110. #if defined (PREFER_STDARG)
  111. programming_error (const char *format, ...)
  112. #else
  113. programming_error (format, va_alist)
  114. const char *format;
  115. va_dcl
  116. #endif
  117. {
  118. va_list args;
  119. char *h;
  120. #if defined (JOB_CONTROL)
  121. give_terminal_to (shell_pgrp, 0);
  122. #endif /* JOB_CONTROL */
  123. SH_VA_START (args, format);
  124. vfprintf (stderr, format, args);
  125. fprintf (stderr, "\n");
  126. va_end (args);
  127. #if defined (HISTORY)
  128. if (remember_on_history)
  129. {
  130. h = last_history_line ();
  131. fprintf (stderr, _("last command: %s\n"), h ? h : "(null)");
  132. }
  133. #endif
  134. #if 0
  135. fprintf (stderr, "Report this to %s\n", the_current_maintainer);
  136. #endif
  137. fprintf (stderr, _("Aborting..."));
  138. fflush (stderr);
  139. abort ();
  140. }
  141. /* Print an error message and, if `set -e' has been executed, exit the
  142. shell. Used in this file by file_error and programming_error. Used
  143. outside this file mostly to report substitution and expansion errors,
  144. and for bad invocation options. */
  145. void
  146. #if defined (PREFER_STDARG)
  147. report_error (const char *format, ...)
  148. #else
  149. report_error (format, va_alist)
  150. const char *format;
  151. va_dcl
  152. #endif
  153. {
  154. va_list args;
  155. error_prolog (1);
  156. SH_VA_START (args, format);
  157. vfprintf (stderr, format, args);
  158. fprintf (stderr, "\n");
  159. va_end (args);
  160. if (exit_immediately_on_error)
  161. exit_shell (1);
  162. }
  163. void
  164. #if defined (PREFER_STDARG)
  165. fatal_error (const char *format, ...)
  166. #else
  167. fatal_error (format, va_alist)
  168. const char *format;
  169. va_dcl
  170. #endif
  171. {
  172. va_list args;
  173. error_prolog (0);
  174. SH_VA_START (args, format);
  175. vfprintf (stderr, format, args);
  176. fprintf (stderr, "\n");
  177. va_end (args);
  178. sh_exit (2);
  179. }
  180. void
  181. #if defined (PREFER_STDARG)
  182. internal_error (const char *format, ...)
  183. #else
  184. internal_error (format, va_alist)
  185. const char *format;
  186. va_dcl
  187. #endif
  188. {
  189. va_list args;
  190. error_prolog (1);
  191. SH_VA_START (args, format);
  192. vfprintf (stderr, format, args);
  193. fprintf (stderr, "\n");
  194. va_end (args);
  195. }
  196. void
  197. #if defined (PREFER_STDARG)
  198. internal_warning (const char *format, ...)
  199. #else
  200. internal_warning (format, va_alist)
  201. const char *format;
  202. va_dcl
  203. #endif
  204. {
  205. va_list args;
  206. error_prolog (1);
  207. fprintf (stderr, _("warning: "));
  208. SH_VA_START (args, format);
  209. vfprintf (stderr, format, args);
  210. fprintf (stderr, "\n");
  211. va_end (args);
  212. }
  213. void
  214. #if defined (PREFER_STDARG)
  215. sys_error (const char *format, ...)
  216. #else
  217. sys_error (format, va_alist)
  218. const char *format;
  219. va_dcl
  220. #endif
  221. {
  222. int e;
  223. va_list args;
  224. e = errno;
  225. error_prolog (0);
  226. SH_VA_START (args, format);
  227. vfprintf (stderr, format, args);
  228. fprintf (stderr, ": %s\n", strerror (e));
  229. va_end (args);
  230. }
  231. /* An error from the parser takes the general form
  232. shell_name: input file name: line number: message
  233. The input file name and line number are omitted if the shell is
  234. currently interactive. If the shell is not currently interactive,
  235. the input file name is inserted only if it is different from the
  236. shell name. */
  237. void
  238. #if defined (PREFER_STDARG)
  239. parser_error (int lineno, const char *format, ...)
  240. #else
  241. parser_error (lineno, format, va_alist)
  242. int lineno;
  243. const char *format;
  244. va_dcl
  245. #endif
  246. {
  247. va_list args;
  248. char *ename, *iname;
  249. ename = get_name_for_error ();
  250. iname = yy_input_name ();
  251. if (interactive)
  252. fprintf (stderr, "%s: ", ename);
  253. else if (interactive_shell)
  254. fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno);
  255. else if (STREQ (ename, iname))
  256. fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), lineno);
  257. else
  258. fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno);
  259. SH_VA_START (args, format);
  260. vfprintf (stderr, format, args);
  261. fprintf (stderr, "\n");
  262. va_end (args);
  263. if (exit_immediately_on_error)
  264. exit_shell (2);
  265. }
  266. #ifdef DEBUG
  267. void
  268. #if defined (PREFER_STDARG)
  269. itrace (const char *format, ...)
  270. #else
  271. itrace (format, va_alist)
  272. const char *format;
  273. va_dcl
  274. #endif
  275. {
  276. va_list args;
  277. fprintf(stderr, "TRACE: pid %ld: ", (long)getpid());
  278. SH_VA_START (args, format);
  279. vfprintf (stderr, format, args);
  280. fprintf (stderr, "\n");
  281. va_end (args);
  282. fflush(stderr);
  283. }
  284. /* A trace function for silent debugging -- doesn't require a control
  285. terminal. */
  286. void
  287. #if defined (PREFER_STDARG)
  288. trace (const char *format, ...)
  289. #else
  290. trace (format, va_alist)
  291. const char *format;
  292. va_dcl
  293. #endif
  294. {
  295. va_list args;
  296. static FILE *tracefp = (FILE *)NULL;
  297. if (tracefp == NULL)
  298. tracefp = fopen("/tmp/bash-trace.log", "a+");
  299. if (tracefp == NULL)
  300. tracefp = stderr;
  301. else
  302. fcntl (fileno (tracefp), F_SETFD, 1); /* close-on-exec */
  303. fprintf(tracefp, "TRACE: pid %ld: ", (long)getpid());
  304. SH_VA_START (args, format);
  305. vfprintf (tracefp, format, args);
  306. fprintf (tracefp, "\n");
  307. va_end (args);
  308. fflush(tracefp);
  309. }
  310. #endif /* DEBUG */
  311. /* **************************************************************** */
  312. /* */
  313. /* Common error reporting */
  314. /* */
  315. /* **************************************************************** */
  316. static const char * const cmd_error_table[] = {
  317. N_("unknown command error"), /* CMDERR_DEFAULT */
  318. N_("bad command type"), /* CMDERR_BADTYPE */
  319. N_("bad connector"), /* CMDERR_BADCONN */
  320. N_("bad jump"), /* CMDERR_BADJUMP */
  321. 0
  322. };
  323. void
  324. command_error (func, code, e, flags)
  325. const char *func;
  326. int code, e, flags; /* flags currently unused */
  327. {
  328. if (code > CMDERR_LAST)
  329. code = CMDERR_DEFAULT;
  330. programming_error ("%s: %s: %d", func, _(cmd_error_table[code]), e);
  331. }
  332. char *
  333. command_errstr (code)
  334. int code;
  335. {
  336. if (code > CMDERR_LAST)
  337. code = CMDERR_DEFAULT;
  338. return (_(cmd_error_table[code]));
  339. }
  340. #ifdef ARRAY_VARS
  341. void
  342. err_badarraysub (s)
  343. const char *s;
  344. {
  345. report_error ("%s: %s", s, _(bash_badsub_errmsg));
  346. }
  347. #endif
  348. void
  349. err_unboundvar (s)
  350. const char *s;
  351. {
  352. report_error (_("%s: unbound variable"), s);
  353. }
  354. void
  355. err_readonly (s)
  356. const char *s;
  357. {
  358. report_error (_("%s: readonly variable"), s);
  359. }