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