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