1 | /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
2 | // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: |
3 | #ident "$Id$" |
4 | /*====== |
5 | This file is part of PerconaFT. |
6 | |
7 | |
8 | Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. |
9 | |
10 | PerconaFT is free software: you can redistribute it and/or modify |
11 | it under the terms of the GNU General Public License, version 2, |
12 | as published by the Free Software Foundation. |
13 | |
14 | PerconaFT is distributed in the hope that it will be useful, |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | GNU General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU General Public License |
20 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
21 | |
22 | ---------------------------------------- |
23 | |
24 | PerconaFT is free software: you can redistribute it and/or modify |
25 | it under the terms of the GNU Affero General Public License, version 3, |
26 | as published by the Free Software Foundation. |
27 | |
28 | PerconaFT is distributed in the hope that it will be useful, |
29 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
30 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
31 | GNU Affero General Public License for more details. |
32 | |
33 | You should have received a copy of the GNU Affero General Public License |
34 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
35 | ======= */ |
36 | |
37 | #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." |
38 | |
39 | /** |
40 | \file errors.c |
41 | \brief Error handling |
42 | |
43 | The error handling routines for ydb |
44 | */ |
45 | |
46 | #include <toku_portability.h> |
47 | #include <stdio.h> |
48 | #include <stdarg.h> |
49 | |
50 | #include "ydb-internal.h" |
51 | |
52 | /** Checks whether the environment has panicked */ |
53 | int toku_env_is_panicked(DB_ENV *dbenv /**< The environment to check */) { |
54 | if (dbenv==0) return 0; |
55 | return dbenv->i->is_panicked; |
56 | } |
57 | |
58 | /* Prints an error message to a file specified by env (or stderr), |
59 | preceded by the environment's error prefix. */ |
60 | static void toku__ydb_error_file(const DB_ENV *env, bool use_stderr, |
61 | char errmsg[]) { |
62 | /* Determine the error file to use */ |
63 | FILE *CAST_FROM_VOIDP(efile, env->i->errfile); |
64 | if (efile==NULL && env->i->errcall==0 && use_stderr) efile = stderr; |
65 | |
66 | /* Print out on a file */ |
67 | if (efile) { |
68 | if (env->i->errpfx) fprintf(efile, "%s: " , env->i->errpfx); |
69 | fprintf(efile, "%s" , errmsg); |
70 | } |
71 | } |
72 | |
73 | /** |
74 | |
75 | Prints out environment errors, adjusting to a variety of options |
76 | and formats. |
77 | The printout format can be controlled to print the following optional |
78 | messages: |
79 | - The environment error message prefix |
80 | - User-supplied prefix obtained by printing ap with the |
81 | fmt string |
82 | - The standard db error string |
83 | The print out takes place via errcall (if set), errfile (if set), |
84 | or stderr if neither is set (and the user so toggles the printout). |
85 | Both errcall and errfile can be set. |
86 | The error message is truncated to approximately 4,000 characters. |
87 | |
88 | \param env The environment that the error refers to. |
89 | \param error The error code |
90 | \param include_stderrstring Controls whether the standard db error |
91 | string should be included in the print out |
92 | \param use_stderr_if_nothing_else Toggles the use of stderr. |
93 | \param fmt Output format for optional prefix arguments (must be NULL |
94 | if the prefix is empty) |
95 | \param ap Optional prefix |
96 | */ |
97 | void toku_ydb_error_all_cases(const DB_ENV * env, |
98 | int error, |
99 | bool include_stderrstring, |
100 | bool use_stderr_if_nothing_else, |
101 | const char *fmt, va_list ap) { |
102 | /* Construct the error message */ |
103 | char buf [4000]; |
104 | int count=0; |
105 | if (fmt) count=vsnprintf(buf, sizeof(buf), fmt, ap); |
106 | if (include_stderrstring) { |
107 | count+=snprintf(&buf[count], sizeof(buf)-count, ": %s" , |
108 | db_strerror(error)); |
109 | } |
110 | |
111 | /* Print via errcall */ |
112 | if (env->i->errcall) env->i->errcall(env, env->i->errpfx, buf); |
113 | |
114 | /* Print out on a file */ |
115 | toku__ydb_error_file(env, use_stderr_if_nothing_else, buf); |
116 | } |
117 | |
118 | /** Handle all the error cases (but don't do the default thing.) |
119 | \param dbenv The environment that is subject to errors |
120 | \param error The error code |
121 | \param fmt The format string for additional variable arguments to |
122 | be printed */ |
123 | int toku_ydb_do_error (const DB_ENV *dbenv, int error, const char *fmt, ...) { |
124 | va_list ap; |
125 | va_start(ap, fmt); |
126 | toku_ydb_error_all_cases(dbenv, error, false, false, fmt, ap); |
127 | va_end(ap); |
128 | return error; |
129 | } |
130 | |
131 | /** Handle errors on an environment, |
132 | \param dbenv The environment that is subject to errors |
133 | \param error The error code |
134 | \param fmt The format string for additional variable arguments to |
135 | be printed */ |
136 | void toku_env_err(const DB_ENV * env, int error, const char *fmt, ...) { |
137 | va_list ap; |
138 | va_start(ap, fmt); |
139 | toku_ydb_error_all_cases(env, error, false, true, fmt, ap); |
140 | va_end(ap); |
141 | } |
142 | |