error.c revision 1.1.1.1 1 1.1 jmmv /*
2 1.1 jmmv * Automated Testing Framework (atf)
3 1.1 jmmv *
4 1.1 jmmv * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 1.1 jmmv * All rights reserved.
6 1.1 jmmv *
7 1.1 jmmv * Redistribution and use in source and binary forms, with or without
8 1.1 jmmv * modification, are permitted provided that the following conditions
9 1.1 jmmv * are met:
10 1.1 jmmv * 1. Redistributions of source code must retain the above copyright
11 1.1 jmmv * notice, this list of conditions and the following disclaimer.
12 1.1 jmmv * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 jmmv * notice, this list of conditions and the following disclaimer in the
14 1.1 jmmv * documentation and/or other materials provided with the distribution.
15 1.1 jmmv *
16 1.1 jmmv * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17 1.1 jmmv * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 1.1 jmmv * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 1.1 jmmv * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 1.1 jmmv * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21 1.1 jmmv * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 1.1 jmmv * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 1.1 jmmv * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 1.1 jmmv * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 1.1 jmmv * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 1.1 jmmv * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 1.1 jmmv * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 1.1 jmmv */
29 1.1 jmmv
30 1.1 jmmv #include <stdarg.h>
31 1.1 jmmv #include <stdio.h>
32 1.1 jmmv #include <stdlib.h>
33 1.1 jmmv #include <string.h>
34 1.1 jmmv
35 1.1 jmmv #include "atf-c/error.h"
36 1.1 jmmv #include "atf-c/sanity.h"
37 1.1 jmmv
38 1.1 jmmv /* ---------------------------------------------------------------------
39 1.1 jmmv * Auxiliary functions.
40 1.1 jmmv * --------------------------------------------------------------------- */
41 1.1 jmmv
42 1.1 jmmv static
43 1.1 jmmv void
44 1.1 jmmv error_format(const atf_error_t err, char *buf, size_t buflen)
45 1.1 jmmv {
46 1.1 jmmv PRE(err != NULL);
47 1.1 jmmv snprintf(buf, buflen, "Error '%s'", err->m_type);
48 1.1 jmmv }
49 1.1 jmmv
50 1.1 jmmv static
51 1.1 jmmv bool
52 1.1 jmmv error_init(atf_error_t err, const char *type, void *data, size_t datalen,
53 1.1 jmmv void (*format)(const atf_error_t, char *, size_t))
54 1.1 jmmv {
55 1.1 jmmv bool ok;
56 1.1 jmmv
57 1.1 jmmv PRE(data != NULL || datalen == 0);
58 1.1 jmmv PRE(datalen != 0 || data == NULL);
59 1.1 jmmv
60 1.1 jmmv atf_object_init(&err->m_object);
61 1.1 jmmv
62 1.1 jmmv err->m_free = false;
63 1.1 jmmv err->m_type = type;
64 1.1 jmmv err->m_format = (format == NULL) ? error_format : format;
65 1.1 jmmv
66 1.1 jmmv ok = true;
67 1.1 jmmv if (data == NULL) {
68 1.1 jmmv err->m_data = NULL;
69 1.1 jmmv } else {
70 1.1 jmmv err->m_data = malloc(datalen);
71 1.1 jmmv if (err->m_data == NULL)
72 1.1 jmmv ok = false;
73 1.1 jmmv else
74 1.1 jmmv memcpy(err->m_data, data, datalen);
75 1.1 jmmv }
76 1.1 jmmv
77 1.1 jmmv return ok;
78 1.1 jmmv }
79 1.1 jmmv
80 1.1 jmmv /* ---------------------------------------------------------------------
81 1.1 jmmv * The "atf_error" type.
82 1.1 jmmv * --------------------------------------------------------------------- */
83 1.1 jmmv
84 1.1 jmmv atf_error_t
85 1.1 jmmv atf_error_new(const char *type, void *data, size_t datalen,
86 1.1 jmmv void (*format)(const atf_error_t, char *, size_t))
87 1.1 jmmv {
88 1.1 jmmv atf_error_t err;
89 1.1 jmmv
90 1.1 jmmv PRE(data != NULL || datalen == 0);
91 1.1 jmmv PRE(datalen != 0 || data == NULL);
92 1.1 jmmv
93 1.1 jmmv err = malloc(sizeof(*err));
94 1.1 jmmv if (err == NULL)
95 1.1 jmmv err = atf_no_memory_error();
96 1.1 jmmv else {
97 1.1 jmmv if (!error_init(err, type, data, datalen, format)) {
98 1.1 jmmv free(err);
99 1.1 jmmv err = atf_no_memory_error();
100 1.1 jmmv } else
101 1.1 jmmv err->m_free = true;
102 1.1 jmmv }
103 1.1 jmmv
104 1.1 jmmv INV(err != NULL);
105 1.1 jmmv return err;
106 1.1 jmmv }
107 1.1 jmmv
108 1.1 jmmv void
109 1.1 jmmv atf_error_free(atf_error_t err)
110 1.1 jmmv {
111 1.1 jmmv bool freeit;
112 1.1 jmmv
113 1.1 jmmv PRE(err != NULL);
114 1.1 jmmv
115 1.1 jmmv freeit = err->m_free;
116 1.1 jmmv
117 1.1 jmmv if (err->m_data != NULL)
118 1.1 jmmv free(err->m_data);
119 1.1 jmmv
120 1.1 jmmv atf_object_fini(&err->m_object);
121 1.1 jmmv
122 1.1 jmmv if (freeit)
123 1.1 jmmv free(err);
124 1.1 jmmv }
125 1.1 jmmv
126 1.1 jmmv atf_error_t
127 1.1 jmmv atf_no_error(void)
128 1.1 jmmv {
129 1.1 jmmv return NULL;
130 1.1 jmmv }
131 1.1 jmmv
132 1.1 jmmv bool
133 1.1 jmmv atf_is_error(const atf_error_t err)
134 1.1 jmmv {
135 1.1 jmmv return err != NULL;
136 1.1 jmmv }
137 1.1 jmmv
138 1.1 jmmv bool
139 1.1 jmmv atf_error_is(const atf_error_t err, const char *type)
140 1.1 jmmv {
141 1.1 jmmv PRE(err != NULL);
142 1.1 jmmv
143 1.1 jmmv return strcmp(err->m_type, type) == 0;
144 1.1 jmmv }
145 1.1 jmmv
146 1.1 jmmv const void *
147 1.1 jmmv atf_error_data(const atf_error_t err)
148 1.1 jmmv {
149 1.1 jmmv PRE(err != NULL);
150 1.1 jmmv
151 1.1 jmmv return err->m_data;
152 1.1 jmmv }
153 1.1 jmmv
154 1.1 jmmv void
155 1.1 jmmv atf_error_format(const atf_error_t err, char *buf, size_t buflen)
156 1.1 jmmv {
157 1.1 jmmv PRE(err != NULL);
158 1.1 jmmv err->m_format(err, buf, buflen);
159 1.1 jmmv }
160 1.1 jmmv
161 1.1 jmmv /* ---------------------------------------------------------------------
162 1.1 jmmv * Common error types.
163 1.1 jmmv * --------------------------------------------------------------------- */
164 1.1 jmmv
165 1.1 jmmv /*
166 1.1 jmmv * The "libc" error.
167 1.1 jmmv */
168 1.1 jmmv
169 1.1 jmmv struct atf_libc_error_data {
170 1.1 jmmv int m_errno;
171 1.1 jmmv char m_what[4096];
172 1.1 jmmv };
173 1.1 jmmv typedef struct atf_libc_error_data atf_libc_error_data_t;
174 1.1 jmmv
175 1.1 jmmv static
176 1.1 jmmv void
177 1.1 jmmv libc_format(const atf_error_t err, char *buf, size_t buflen)
178 1.1 jmmv {
179 1.1 jmmv const atf_libc_error_data_t *data;
180 1.1 jmmv
181 1.1 jmmv PRE(atf_error_is(err, "libc"));
182 1.1 jmmv
183 1.1 jmmv data = atf_error_data(err);
184 1.1 jmmv snprintf(buf, buflen, "%s: %s", data->m_what, strerror(data->m_errno));
185 1.1 jmmv }
186 1.1 jmmv
187 1.1 jmmv atf_error_t
188 1.1 jmmv atf_libc_error(int syserrno, const char *fmt, ...)
189 1.1 jmmv {
190 1.1 jmmv atf_error_t err;
191 1.1 jmmv atf_libc_error_data_t data;
192 1.1 jmmv va_list ap;
193 1.1 jmmv
194 1.1 jmmv data.m_errno = syserrno;
195 1.1 jmmv va_start(ap, fmt);
196 1.1 jmmv vsnprintf(data.m_what, sizeof(data.m_what), fmt, ap);
197 1.1 jmmv va_end(ap);
198 1.1 jmmv
199 1.1 jmmv err = atf_error_new("libc", &data, sizeof(data), libc_format);
200 1.1 jmmv
201 1.1 jmmv return err;
202 1.1 jmmv }
203 1.1 jmmv
204 1.1 jmmv int
205 1.1 jmmv atf_libc_error_code(const atf_error_t err)
206 1.1 jmmv {
207 1.1 jmmv const struct atf_libc_error_data *data;
208 1.1 jmmv
209 1.1 jmmv PRE(atf_error_is(err, "libc"));
210 1.1 jmmv
211 1.1 jmmv data = atf_error_data(err);
212 1.1 jmmv
213 1.1 jmmv return data->m_errno;
214 1.1 jmmv }
215 1.1 jmmv
216 1.1 jmmv /*
217 1.1 jmmv * The "no_memory" error.
218 1.1 jmmv */
219 1.1 jmmv
220 1.1 jmmv static bool no_memory_error_inited = false;
221 1.1 jmmv static struct atf_error no_memory_error;
222 1.1 jmmv
223 1.1 jmmv static
224 1.1 jmmv void
225 1.1 jmmv no_memory_format(const atf_error_t err, char *buf, size_t buflen)
226 1.1 jmmv {
227 1.1 jmmv PRE(atf_error_is(err, "no_memory"));
228 1.1 jmmv
229 1.1 jmmv snprintf(buf, buflen, "Not enough memory");
230 1.1 jmmv }
231 1.1 jmmv
232 1.1 jmmv atf_error_t
233 1.1 jmmv atf_no_memory_error(void)
234 1.1 jmmv {
235 1.1 jmmv if (!no_memory_error_inited) {
236 1.1 jmmv error_init(&no_memory_error, "no_memory", NULL, 0,
237 1.1 jmmv no_memory_format);
238 1.1 jmmv no_memory_error_inited = true;
239 1.1 jmmv }
240 1.1 jmmv
241 1.1 jmmv return &no_memory_error;
242 1.1 jmmv }
243