xref: /haiku/src/system/libroot/posix/string/strerror.c (revision 24159a0c7d6d6dcba9f2a0c1a7c08d2c8167f21b)
1 /*
2  * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT license.
4  *
5  * Copyright 2001, Dan Sinclair. All rights reserved.
6  * Distributed under the terms of the NewOS License.
7  */
8 
9 
10 #include <SupportDefs.h>
11 #include <translation/TranslationErrors.h>
12 
13 #include <string.h>
14 #include <stdio.h>
15 
16 
17 static const struct error_base {
18 	int			base;
19 	const char	*name;
20 } kErrorBases[] = {
21 	{B_GENERAL_ERROR_BASE, "General "},
22 	{B_OS_ERROR_BASE, "OS "},
23 	{B_APP_ERROR_BASE, "Application Kit "},
24 	{B_INTERFACE_ERROR_BASE, "Interface Kit "},
25 	{B_MEDIA_ERROR_BASE, "Media Kit "},
26 	{B_MEDIA_ERROR_BASE + 0x200, ""},
27 	{B_TRANSLATION_ERROR_BASE, "Translation Kit "},
28 	{B_MEDIA_ERROR_BASE + 0x100, ""},
29 	{B_MIDI_ERROR_BASE, "Midi Kit "},
30 	{B_STORAGE_ERROR_BASE, "Storage Kit "},
31 	{B_POSIX_ERROR_BASE, "POSIX "},
32 	{B_MAIL_ERROR_BASE, "Mail Kit "},
33 	{B_PRINT_ERROR_BASE, "Print "},
34 	{B_DEVICE_ERROR_BASE, "Device "},
35 	{B_ERRORS_END, "Application "},
36 };
37 static const uint32 kNumErrorBases = sizeof(kErrorBases) / sizeof(struct error_base);
38 
39 
40 static char *
41 error_description(int error)
42 {
43 	switch (error) {
44 		// General Errors
45 
46 		case B_NO_ERROR:
47 			return "No error";
48 		case B_ERROR:
49 			return "General system error";
50 
51 		case B_NO_MEMORY:
52 			// ENOMEM
53 			return "Out of memory";
54 		case B_IO_ERROR:
55 			// EIO
56 			return "I/O error";
57 		case B_PERMISSION_DENIED:
58 			// EACCES
59 			return "Permission denied";
60 		case B_BAD_INDEX:
61 			return "Index not in range for the data set";
62 		case B_BAD_TYPE:
63 			return "Bad argument type passed to function";
64 		case B_BAD_VALUE:
65 			// EINVAL
66 			return "Invalid Argument";
67 		case B_MISMATCHED_VALUES:
68 			return "Mismatched values passed to function";
69 		case B_NAME_NOT_FOUND:
70 			return "Name not found";
71 		case B_NAME_IN_USE:
72 			return "Name in use";
73 		case B_TIMED_OUT:
74 			// ETIMEDOUT
75 			return "Operation timed out";
76 		case B_INTERRUPTED:
77 			// EINTR
78 			return "Interrupted system call";
79 		case B_WOULD_BLOCK:
80 			// EAGAIN
81 			// EWOULDBLOCK
82 			return "Operation would block";
83 		case B_CANCELED:
84 			return "Operation canceled";
85 		case B_NO_INIT:
86 			return "Initialization failed";
87 		case B_BUSY:
88 			// EBUSY
89 			return "Device/File/Resource busy";
90 		case B_NOT_ALLOWED:
91 			// EPERM
92 			return "Operation not allowed";
93 		case B_BAD_DATA:
94 			return "Bad data";
95 
96 		// Kernel Kit Errors
97 
98 		case B_BAD_SEM_ID:
99 			return "Bad semaphore ID";
100 		case B_NO_MORE_SEMS:
101 			return "No more semaphores";
102 
103 		case B_BAD_THREAD_ID:
104 			return "Bad thread ID";
105 		case B_NO_MORE_THREADS:
106 			return "No more threads";
107 		case B_BAD_THREAD_STATE:
108 			return "Thread is inappropriate state";
109 		case B_BAD_TEAM_ID:
110 			return "Operation on invalid team";
111 		case B_NO_MORE_TEAMS:
112 			return "No more teams";
113 
114 		case B_BAD_PORT_ID:
115 			return "Bad port ID";
116 		case B_NO_MORE_PORTS:
117 			return "No more ports available";	// "No more ports"
118 
119 		case B_BAD_IMAGE_ID:
120 			return "Bad image ID";
121 		case B_BAD_ADDRESS:
122 			// EFAULT
123 			return "Bad address";
124 		case B_NOT_AN_EXECUTABLE:
125 			// ENOEXEC
126 			return "Not an executable";
127 		case B_MISSING_LIBRARY:
128 			return "Missing library";
129 		case B_MISSING_SYMBOL:
130 			return "Symbol not found";
131 
132 		case B_DEBUGGER_ALREADY_INSTALLED:
133 			return "Debugger already installed for this team";
134 
135 		// Application Kit Errors
136 
137 		case B_BAD_REPLY:
138 			return "Invalid or unwanted reply";
139 		case B_DUPLICATE_REPLY:
140 			return "Duplicate reply";
141 		case B_MESSAGE_TO_SELF:
142 			return "Can't send message to self";
143 		case B_BAD_HANDLER:
144 			return "Bad handler";
145 		case B_ALREADY_RUNNING:
146 			return "Already running";
147 		case B_LAUNCH_FAILED:
148 			return "Launch failed";
149 		case B_AMBIGUOUS_APP_LAUNCH:
150 			return "Ambiguous app launch";
151 		case B_UNKNOWN_MIME_TYPE:
152 			return "Unknown MIME type";
153 		case B_BAD_SCRIPT_SYNTAX:
154 			return "Bad script syntax";
155 		case B_LAUNCH_FAILED_NO_RESOLVE_LINK:
156 			return "Could not resolve a link";
157 		case B_LAUNCH_FAILED_EXECUTABLE:
158 			return "File is mistakenly marked as executable";
159 		case B_LAUNCH_FAILED_APP_NOT_FOUND:
160 			return "Application could not be found";
161 		case B_LAUNCH_FAILED_APP_IN_TRASH:
162 			return "Application is in the trash";
163 		case B_LAUNCH_FAILED_NO_PREFERRED_APP:
164 			return "There is no preferred application for this type of file";
165 		case B_LAUNCH_FAILED_FILES_APP_NOT_FOUND:
166 			return "This file has a preferred app, but it could not be found";
167 		case B_BAD_MIME_SNIFFER_RULE:
168 			return "Bad sniffer rule";
169 		case B_NOT_A_MESSAGE:
170 			return "Data is not a message";
171 		case B_SHUTDOWN_CANCELLED:
172 			return "System shutdown cancelled";
173 		case B_SHUTTING_DOWN:
174 			return "System shutting down";
175 
176 		// Storage Kit Errors
177 
178 		case B_FILE_ERROR:
179 			// EBADF
180 			return "Bad file descriptor";
181 		case B_FILE_NOT_FOUND:
182 		case B_ENTRY_NOT_FOUND:
183 			// ENOENT
184 			return "No such file or directory";
185 		case B_FILE_EXISTS:
186 			// EEXIST
187 			return "File or Directory already exists";
188 		case B_NAME_TOO_LONG:
189 			//	ENAMETOOLONG
190 			return "File name too long";
191 		case B_NOT_A_DIRECTORY:
192 			// ENOTDIR
193 			return "Not a directory";
194 		case B_DIRECTORY_NOT_EMPTY:
195 			// ENOTEMPTY
196 			return "Directory not empty";
197 		case B_DEVICE_FULL:
198 			// ENOSPC
199 			return "No space left on device";
200 		case B_READ_ONLY_DEVICE:
201 			// EROFS:
202 			return "Read-only file system";
203 		case B_IS_A_DIRECTORY:
204 			// EISDIR
205 			return "Is a directory";
206 		case B_NO_MORE_FDS:
207 			// EMFILE
208 			return "Too many open files";
209 		case B_CROSS_DEVICE_LINK:
210 			// EXDEV
211 			return "Cross-device link";
212 		case B_LINK_LIMIT:
213 			// ELOOP
214 			return "Too many symbolic links";
215 		case B_BUSTED_PIPE:
216 			// EPIPE
217 			return "Broken pipe";
218 		case B_UNSUPPORTED:
219 			return "Operation not supported";
220 		case B_PARTITION_TOO_SMALL:
221 			return "Partition too small to contain filesystem";
222 
223 		// Media Kit Errors
224 
225 		case B_STREAM_NOT_FOUND:
226 			return "Stream not found";
227 		case B_SERVER_NOT_FOUND:
228 			return "Server not found";
229 		case B_RESOURCE_NOT_FOUND:
230 			return "Resource not found";
231 		case B_RESOURCE_UNAVAILABLE:
232 			return "Resource unavailable";
233 		case B_BAD_SUBSCRIBER:
234 			return "Bad subscriber";
235 		case B_SUBSCRIBER_NOT_ENTERED:
236 			return "Subscriber not entered";
237 		case B_BUFFER_NOT_AVAILABLE:
238 			return "Buffer not available";
239 		case B_LAST_BUFFER_ERROR:
240 			return "Last buffer";
241 
242 		// Mail Kit Errors
243 
244 		case B_MAIL_NO_DAEMON:
245 			return "No mail daemon";
246 		case B_MAIL_UNKNOWN_USER:
247 			return "Unknown mail user";
248 		case B_MAIL_WRONG_PASSWORD:
249 			return "Wrong password (mail)";
250 		case B_MAIL_UNKNOWN_HOST:
251 			return "Mail unknown host";
252 		case B_MAIL_ACCESS_ERROR:
253 			return "Mail access error";
254 		case B_MAIL_UNKNOWN_FIELD:
255 			return "Unknown mail field";
256 		case B_MAIL_NO_RECIPIENT:
257 			return "No mail recipient";
258 		case B_MAIL_INVALID_MAIL:
259 			return "Invaild mail";
260 
261 		// Printing Errors
262 
263 		case B_NO_PRINT_SERVER:
264 			return "No print server";
265 
266 		// Device Kit Errors
267 
268 		case B_DEV_INVALID_IOCTL:
269 			return "Invalid device ioctl";
270 		case B_DEV_NO_MEMORY:
271 			return "No device memory";
272 		case B_DEV_BAD_DRIVE_NUM:
273 			return "Bad drive number";
274 		case B_DEV_NO_MEDIA:
275 			return "No media present";
276 		case B_DEV_UNREADABLE:
277 			return "Device unreadable";
278 		case B_DEV_FORMAT_ERROR:
279 			return "Device format error";
280 		case B_DEV_TIMEOUT:
281 			return "Device timeout";
282 		case B_DEV_RECALIBRATE_ERROR:
283 			return "Device recalibrate error";
284 		case B_DEV_SEEK_ERROR:
285 			return "Device seek error";
286 		case B_DEV_ID_ERROR:
287 			return "Device ID error";
288 		case B_DEV_READ_ERROR:
289 			return "Device read error";
290 		case B_DEV_WRITE_ERROR:
291 			return "Device write error";
292 		case B_DEV_NOT_READY:
293 			return "Device not ready";
294 		case B_DEV_MEDIA_CHANGED:
295 			return "Device media changed";
296 		case B_DEV_MEDIA_CHANGE_REQUESTED:
297 			return "Device media change requested";
298 		case B_DEV_RESOURCE_CONFLICT:
299 			return "Resource conflict";
300 		case B_DEV_CONFIGURATION_ERROR:
301 			return "Configuration error";
302 		case B_DEV_DISABLED_BY_USER:
303 			return "Disabled by user";
304 		case B_DEV_DOOR_OPEN:
305 			return "Drive door open";
306 
307 		// the commented out ones are really strange error codes...
308 		//case B_DEV_INVALID_PIPE:
309 
310 		case B_DEV_CRC_ERROR:
311 			return "Device check-sum error";
312 		case B_DEV_STALLED:
313 			return "Device stalled";
314 
315 		//case B_DEV_BAD_PID:
316 		//case B_DEV_UNEXPECTED_PID:
317 
318 		case B_DEV_DATA_OVERRUN:
319 			return "Device data overrun";
320 		case B_DEV_DATA_UNDERRUN:
321 			return "Device data underrun";
322 		case B_DEV_FIFO_OVERRUN:
323 			return "Device FIFO overrun";
324 		case B_DEV_FIFO_UNDERRUN:
325 			return "Device FIFO underrun";
326 		case B_DEV_PENDING:
327 			return "Device pending";
328 		case B_DEV_MULTIPLE_ERRORS:
329 			return "Multiple device errors";
330 		case B_DEV_TOO_LATE:
331 			return "Device too late";
332 
333 		// Translation Kit Errors
334 
335 		case B_NO_TRANSLATOR:
336 			return "No translator found";
337 		case B_ILLEGAL_DATA:
338 			return "";
339 
340 		// Other POSIX Errors
341 
342 		case ENFILE:
343 			return "File table overflow";
344 		case ENXIO:
345 			return "Device not accessible";
346 		case ESPIPE:
347 			return "Seek not allowed on file descriptor";
348 		case ENOSYS:
349 			return "Function not implemented";
350 		case EDOM:
351 			return "Numerical argument out of range";	// "Domain Error"
352 		case ENOBUFS:
353 			return "No buffer space available";
354 		case E2BIG:
355 			return "Argument too big";
356 		case ECHILD:
357 			return "No child process";
358 		case EDEADLK:
359 			return "Resource deadlock";
360 		case EFBIG:
361 			return "File too large";
362 		case EMLINK:
363 			return "Too many links";
364 		case ENODEV:
365 			return "No such device";
366 		case ENOLCK:
367 			return "No record locks available";
368 		case ENOTTY:
369 			return "Not a tty";
370 		case ESRCH:
371 			return "No such process";
372 		case EFPOS:
373 			return "File Position Error";
374 		case ESIGPARM:
375 			return "Signal Error";
376 		case ERANGE:
377 			return "Range Error";
378 
379 		case EPROTOTYPE:
380 			return "Protocol wrong type for socket";
381 		case EPROTONOSUPPORT:
382 			return "Protocol not supported";
383 		case EPFNOSUPPORT:
384 			return "Protocol family not supported";
385 		case EAFNOSUPPORT:
386 			return "Address family not supported by protocol family";
387 		case EADDRINUSE:
388 			return "Address already in use";
389 		case EADDRNOTAVAIL:
390 			return "Can't assign requested address";
391 		case ENETDOWN:
392 			return "Network is down";
393 		case ENETUNREACH:
394 			return "Network is unreachable";
395 		case ENETRESET:
396 			return "Network dropped connection on reset";
397 		case ECONNABORTED:
398 			return "Software caused connection abort";
399 		case ECONNRESET:
400 			return "Connection reset by peer";
401 		case EISCONN:
402 			return "Socket is already connected";
403 		case ENOTCONN:
404 			return "Socket is not connected";
405 		case ESHUTDOWN:
406 			return "Can't send after socket shutdown";
407 		case ECONNREFUSED:
408 			return "Connection refused";
409 		case EHOSTUNREACH:
410 			return "No route to host";
411 		case ENOPROTOOPT:
412 			return "Protocol option not available";
413 		case EINPROGRESS:
414 			return "Operation now in progress";
415 		case EALREADY:
416 			return "Operation already in progress";
417 		case EILSEQ:
418 			return "Illegal byte sequence";
419 		case ENOMSG:
420 			return "No message of desired type";
421 		case ESTALE:
422 			return "Stale file handle";
423 
424 		case EOVERFLOW:
425 			return "Value too large for defined type";
426 		case EMSGSIZE:
427 			return "Message too long";
428 		case EOPNOTSUPP:
429 			return "Operation not supported";
430 		case ENOTSOCK:
431 			return "Socket operation on non-socket";
432 		case EBADMSG:
433 			return "Bad message";
434 		case ECANCELED:
435 			return "Operation canceled";
436 		case EDESTADDRREQ:
437 			return "Destination address required";
438 		case EDQUOT:
439 			return "Reserved";
440 		case EIDRM:
441 			return "Identifier removed";
442 		case EMULTIHOP:
443 			return "Reserved";
444 		case ENODATA:
445 			return "No message available";
446 		case ENOLINK:
447 			return "Reserved";
448 		case ENOSR:
449 			return "No STREAM resources";
450 		case ENOSTR:
451 			return "Not a STREAM";
452 		case ENOTSUP:
453 			return "Not supported";
454 		case EPROTO:
455 			return "Protocol error";
456 		case ETIME:
457 			return "STREAM ioctl() timeout";
458 		case ETXTBSY:
459 			return "Text file busy";
460 
461 		default:
462 			return NULL;
463 	}
464 }
465 
466 
467 char *
468 strerror(int error)
469 {
470 	static char unknown[48];
471 	uint32 i;
472 
473 	char *description = error_description(error);
474 	if (description != NULL)
475 		return description;
476 
477 	if (error < B_OK) {
478 		const char *system = "";
479 		for (i = 0; i < kNumErrorBases; i++) {
480 			if (kErrorBases[i].base <= error
481 				&& ((i + 1 < kNumErrorBases && kErrorBases[i + 1].base > error)
482 					|| i + 1 == kNumErrorBases)) {
483 				system = kErrorBases[i].name;
484 				break;
485 			}
486 		}
487 		sprintf(unknown, "Unknown %sError (%d)", system, error);
488 	} else
489 		sprintf(unknown, "No Error (%d)", error);
490 
491 	return unknown;
492 }
493 
494 
495 int
496 strerror_r(int error, char *buffer, size_t bufferSize)
497 {
498 	char *description = error_description(error);
499 	if (description == NULL)
500 		return EINVAL;
501 
502 	strlcpy(buffer, description, bufferSize);
503 	return 0;
504 		// ToDo: could return ERANGE if buffer is too small
505 }
506 
507