1/* -*- c-basic-offset: 2 -*- */
2/*
3 Copyright(C) 2013-2017 Brazil
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License version 2.1 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17*/
18
19#include "grn_error.h"
20#include "grn_windows.h"
21
22#ifdef HAVE_ERRNO_H
23#include <errno.h>
24#endif /* HAVE_ERRNO_H */
25
26#include <string.h>
27
28#ifdef WIN32
29
30grn_rc
31grn_windows_error_code_to_rc(int error_code)
32{
33 grn_rc rc;
34
35 switch (error_code) {
36 case ERROR_FILE_NOT_FOUND :
37 case ERROR_PATH_NOT_FOUND :
38 rc = GRN_NO_SUCH_FILE_OR_DIRECTORY;
39 break;
40 case ERROR_TOO_MANY_OPEN_FILES :
41 rc = GRN_TOO_MANY_OPEN_FILES;
42 break;
43 case ERROR_ACCESS_DENIED :
44 rc = GRN_PERMISSION_DENIED;
45 break;
46 case ERROR_INVALID_HANDLE :
47 rc = GRN_INVALID_ARGUMENT;
48 break;
49 case ERROR_ARENA_TRASHED :
50 rc = GRN_ADDRESS_IS_NOT_AVAILABLE;
51 break;
52 case ERROR_NOT_ENOUGH_MEMORY :
53 rc = GRN_NO_MEMORY_AVAILABLE;
54 break;
55 case ERROR_INVALID_BLOCK :
56 case ERROR_BAD_ENVIRONMENT :
57 rc = GRN_INVALID_ARGUMENT;
58 break;
59 case ERROR_BAD_FORMAT :
60 rc = GRN_INVALID_FORMAT;
61 break;
62 case ERROR_INVALID_DATA :
63 rc = GRN_INVALID_ARGUMENT;
64 break;
65 case ERROR_OUTOFMEMORY :
66 rc = GRN_NO_MEMORY_AVAILABLE;
67 break;
68 case ERROR_INVALID_DRIVE :
69 rc = GRN_INVALID_ARGUMENT;
70 break;
71 case ERROR_WRITE_PROTECT :
72 rc = GRN_PERMISSION_DENIED;
73 break;
74 case ERROR_BAD_LENGTH :
75 rc = GRN_INVALID_ARGUMENT;
76 break;
77 case ERROR_SEEK :
78 rc = GRN_INVALID_SEEK;
79 break;
80 case ERROR_NOT_SUPPORTED :
81 rc = GRN_OPERATION_NOT_SUPPORTED;
82 break;
83 case ERROR_NETWORK_ACCESS_DENIED :
84 rc = GRN_OPERATION_NOT_PERMITTED;
85 break;
86 case ERROR_FILE_EXISTS :
87 rc = GRN_FILE_EXISTS;
88 break;
89 case ERROR_INVALID_PARAMETER :
90 rc = GRN_INVALID_ARGUMENT;
91 break;
92 case ERROR_BROKEN_PIPE :
93 rc = GRN_BROKEN_PIPE;
94 break;
95 case ERROR_CALL_NOT_IMPLEMENTED :
96 rc = GRN_FUNCTION_NOT_IMPLEMENTED;
97 break;
98 case ERROR_INVALID_NAME :
99 rc = GRN_INVALID_ARGUMENT;
100 break;
101 case ERROR_BUSY_DRIVE :
102 case ERROR_PATH_BUSY :
103 rc = GRN_RESOURCE_BUSY;
104 break;
105 case ERROR_BAD_ARGUMENTS :
106 rc = GRN_INVALID_ARGUMENT;
107 break;
108 case ERROR_BUSY :
109 rc = GRN_RESOURCE_BUSY;
110 break;
111 case ERROR_ALREADY_EXISTS :
112 rc = GRN_FILE_EXISTS;
113 break;
114 case ERROR_BAD_EXE_FORMAT :
115 rc = GRN_EXEC_FORMAT_ERROR;
116 break;
117 case ERROR_NO_SYSTEM_RESOURCES :
118 rc = GRN_RESOURCE_TEMPORARILY_UNAVAILABLE;
119 break;
120 default:
121 rc = GRN_UNKNOWN_ERROR;
122 break;
123 }
124
125 return rc;
126}
127
128# define LANG_ID_NEUTRAL() MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)
129# define LANG_ID_USER_DEFAULT() MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)
130# define LANG_ID_SYSTEM_DEFAULT() MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT)
131
132const char *
133grn_current_error_message(void)
134{
135# define ERROR_MESSAGE_BUFFER_SIZE 4096
136 int error_code = GetLastError();
137 static WCHAR utf16_message[ERROR_MESSAGE_BUFFER_SIZE];
138 DWORD written_utf16_chars;
139 static char message[ERROR_MESSAGE_BUFFER_SIZE];
140
141 written_utf16_chars = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
142 FORMAT_MESSAGE_IGNORE_INSERTS,
143 NULL,
144 error_code,
145 LANG_ID_USER_DEFAULT(),
146 utf16_message,
147 ERROR_MESSAGE_BUFFER_SIZE,
148 NULL);
149 if (written_utf16_chars >= 2) {
150 if (utf16_message[written_utf16_chars - 1] == L'\n') {
151 utf16_message[written_utf16_chars - 1] = L'\0';
152 written_utf16_chars--;
153 }
154 if (utf16_message[written_utf16_chars - 1] == L'\r') {
155 utf16_message[written_utf16_chars - 1] = L'\0';
156 written_utf16_chars--;
157 }
158 }
159
160 {
161 UINT code_page;
162 DWORD convert_flags = 0;
163 int written_bytes;
164
165 code_page = grn_windows_encoding_to_code_page(grn_get_default_encoding());
166 written_bytes = WideCharToMultiByte(code_page,
167 convert_flags,
168 utf16_message,
169 written_utf16_chars,
170 message,
171 ERROR_MESSAGE_BUFFER_SIZE,
172 NULL,
173 NULL);
174 }
175
176 return message;
177
178# undef ERROR_MESSAGE_BUFFER_SIZE
179}
180#else
181const char *
182grn_current_error_message(void)
183{
184 return strerror(errno);
185}
186#endif
187
188const char *
189grn_strerror(int error_code)
190{
191#ifdef WIN32
192# define MESSAGE_BUFFER_SIZE 1024
193 static char message[MESSAGE_BUFFER_SIZE];
194 strerror_s(message, MESSAGE_BUFFER_SIZE, error_code);
195 return message;
196# undef MESSAGE_BUFFER_SIZE
197#else /* WIN32 */
198 return strerror(error_code);
199#endif /* WIN32 */
200}
201
202const char *
203grn_rc_to_string(grn_rc rc)
204{
205 const char *message = "invalid grn_rc";
206
207 switch (rc) {
208 case GRN_SUCCESS :
209 message = "success";
210 break;
211 case GRN_END_OF_DATA :
212 message = "end of data";
213 break;
214 case GRN_UNKNOWN_ERROR :
215 message = "unknown error";
216 break;
217 case GRN_OPERATION_NOT_PERMITTED :
218 message = "operation not permitted";
219 break;
220 case GRN_NO_SUCH_FILE_OR_DIRECTORY :
221 message = "no such file or directory";
222 break;
223 case GRN_NO_SUCH_PROCESS :
224 message = "no such process";
225 break;
226 case GRN_INTERRUPTED_FUNCTION_CALL :
227 message = "interrupted function call";
228 break;
229 case GRN_INPUT_OUTPUT_ERROR :
230 message = "input output error";
231 break;
232 case GRN_NO_SUCH_DEVICE_OR_ADDRESS :
233 message = "no such device or address";
234 break;
235 case GRN_ARG_LIST_TOO_LONG :
236 message = "argument list is too long";
237 break;
238 case GRN_EXEC_FORMAT_ERROR :
239 message = "exec format error";
240 break;
241 case GRN_BAD_FILE_DESCRIPTOR :
242 message = "bad file descriptor";
243 break;
244 case GRN_NO_CHILD_PROCESSES :
245 message = "no child processes";
246 break;
247 case GRN_RESOURCE_TEMPORARILY_UNAVAILABLE :
248 message = "resource temporarily unavailable";
249 break;
250 case GRN_NOT_ENOUGH_SPACE :
251 message = "not enough space";
252 break;
253 case GRN_PERMISSION_DENIED :
254 message = "permission denied";
255 break;
256 case GRN_BAD_ADDRESS :
257 message = "bad address";
258 break;
259 case GRN_RESOURCE_BUSY :
260 message = "resource busy";
261 break;
262 case GRN_FILE_EXISTS :
263 message = "file exists";
264 break;
265 case GRN_IMPROPER_LINK :
266 message = "improper link";
267 break;
268 case GRN_NO_SUCH_DEVICE :
269 message = "no such device";
270 break;
271 case GRN_NOT_A_DIRECTORY :
272 message = "not a directory";
273 break;
274 case GRN_IS_A_DIRECTORY :
275 message = "is a directory";
276 break;
277 case GRN_INVALID_ARGUMENT :
278 message = "invalid argument";
279 break;
280 case GRN_TOO_MANY_OPEN_FILES_IN_SYSTEM :
281 message = "too many open files in system";
282 break;
283 case GRN_TOO_MANY_OPEN_FILES :
284 message = "too many open files";
285 break;
286 case GRN_INAPPROPRIATE_I_O_CONTROL_OPERATION :
287 message = "inappropriate I/O control operation";
288 break;
289 case GRN_FILE_TOO_LARGE :
290 message = "file too large";
291 break;
292 case GRN_NO_SPACE_LEFT_ON_DEVICE :
293 message = "no space left on device";
294 break;
295 case GRN_INVALID_SEEK :
296 message = "invalid seek";
297 break;
298 case GRN_READ_ONLY_FILE_SYSTEM :
299 message = "read only file system";
300 break;
301 case GRN_TOO_MANY_LINKS :
302 message = "too many links";
303 break;
304 case GRN_BROKEN_PIPE :
305 message = "broken pipe";
306 break;
307 case GRN_DOMAIN_ERROR :
308 message = "domain error";
309 break;
310 case GRN_RESULT_TOO_LARGE :
311 message = "result too large";
312 break;
313 case GRN_RESOURCE_DEADLOCK_AVOIDED :
314 message = "resource deadlock avoided";
315 break;
316 case GRN_NO_MEMORY_AVAILABLE :
317 message = "no memory available";
318 break;
319 case GRN_FILENAME_TOO_LONG :
320 message = "filename too long";
321 break;
322 case GRN_NO_LOCKS_AVAILABLE :
323 message = "no locks available";
324 break;
325 case GRN_FUNCTION_NOT_IMPLEMENTED :
326 message = "function not implemented";
327 break;
328 case GRN_DIRECTORY_NOT_EMPTY :
329 message = "directory not empty";
330 break;
331 case GRN_ILLEGAL_BYTE_SEQUENCE :
332 message = "illegal byte sequence";
333 break;
334 case GRN_SOCKET_NOT_INITIALIZED :
335 message = "socket not initialized";
336 break;
337 case GRN_OPERATION_WOULD_BLOCK :
338 message = "operation would block";
339 break;
340 case GRN_ADDRESS_IS_NOT_AVAILABLE :
341 message = "address is not available";
342 break;
343 case GRN_NETWORK_IS_DOWN :
344 message = "network is down";
345 break;
346 case GRN_NO_BUFFER :
347 message = "no buffer";
348 break;
349 case GRN_SOCKET_IS_ALREADY_CONNECTED :
350 message = "socket is already connected";
351 break;
352 case GRN_SOCKET_IS_NOT_CONNECTED :
353 message = "socket is not connected";
354 break;
355 case GRN_SOCKET_IS_ALREADY_SHUTDOWNED :
356 message = "socket is already shutdowned";
357 break;
358 case GRN_OPERATION_TIMEOUT :
359 message = "operation timeout";
360 break;
361 case GRN_CONNECTION_REFUSED :
362 message = "connection refused";
363 break;
364 case GRN_RANGE_ERROR :
365 message = "range error";
366 break;
367 case GRN_TOKENIZER_ERROR :
368 message = "tokenizer error";
369 break;
370 case GRN_FILE_CORRUPT :
371 message = "file corrupt";
372 break;
373 case GRN_INVALID_FORMAT :
374 message = "invalid format";
375 break;
376 case GRN_OBJECT_CORRUPT :
377 message = "object corrupt";
378 break;
379 case GRN_TOO_MANY_SYMBOLIC_LINKS :
380 message = "too many symbolic links";
381 break;
382 case GRN_NOT_SOCKET :
383 message = "not socket";
384 break;
385 case GRN_OPERATION_NOT_SUPPORTED :
386 message = "operation not supported";
387 break;
388 case GRN_ADDRESS_IS_IN_USE :
389 message = "address is in use";
390 break;
391 case GRN_ZLIB_ERROR :
392 message = "zlib error";
393 break;
394 case GRN_LZ4_ERROR :
395 message = "LZ4 error";
396 break;
397 case GRN_STACK_OVER_FLOW :
398 message = "stack over flow";
399 break;
400 case GRN_SYNTAX_ERROR :
401 message = "syntax error";
402 break;
403 case GRN_RETRY_MAX :
404 message = "retry max";
405 break;
406 case GRN_INCOMPATIBLE_FILE_FORMAT :
407 message = "incompatible file format";
408 break;
409 case GRN_UPDATE_NOT_ALLOWED :
410 message = "update not allowed";
411 break;
412 case GRN_TOO_SMALL_OFFSET :
413 message = "too small offset";
414 break;
415 case GRN_TOO_LARGE_OFFSET :
416 message = "too large offset";
417 break;
418 case GRN_TOO_SMALL_LIMIT :
419 message = "too small limit";
420 break;
421 case GRN_CAS_ERROR :
422 message = "cas error";
423 break;
424 case GRN_UNSUPPORTED_COMMAND_VERSION :
425 message = "unsupported command version";
426 break;
427 case GRN_NORMALIZER_ERROR :
428 message = "normalizer error";
429 break;
430 case GRN_TOKEN_FILTER_ERROR :
431 message = "token filter error";
432 break;
433 case GRN_COMMAND_ERROR :
434 message = "command error";
435 break;
436 case GRN_PLUGIN_ERROR :
437 message = "plugin error";
438 break;
439 case GRN_SCORER_ERROR :
440 message = "scorer error";
441 break;
442 case GRN_CANCEL :
443 message = "cancel";
444 break;
445 case GRN_WINDOW_FUNCTION_ERROR :
446 message = "window function error";
447 break;
448 case GRN_ZSTD_ERROR :
449 message = "Zstandard error";
450 break;
451 }
452
453 return message;
454}
455