xref: /haiku/src/system/libroot/posix/string/strerror.c (revision a71c00d3140e66b5c2f10109c64e14444c3f2a3a)
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 
222 		// Media Kit Errors
223 
224 		case B_STREAM_NOT_FOUND:
225 			return "Stream not found";
226 		case B_SERVER_NOT_FOUND:
227 			return "Server not found";
228 		case B_RESOURCE_NOT_FOUND:
229 			return "Resource not found";
230 		case B_RESOURCE_UNAVAILABLE:
231 			return "Resource unavailable";
232 		case B_BAD_SUBSCRIBER:
233 			return "Bad subscriber";
234 		case B_SUBSCRIBER_NOT_ENTERED:
235 			return "Subscriber not entered";
236 		case B_BUFFER_NOT_AVAILABLE:
237 			return "Buffer not available";
238 		case B_LAST_BUFFER_ERROR:
239 			return "Last buffer";
240 		case B_MEDIA_SYSTEM_FAILURE:
241 			return "System failure";
242 		case B_MEDIA_BAD_NODE:
243 			return "Bad media node";
244 		case B_MEDIA_NODE_BUSY:
245 			return "Media node busy";
246 		case B_MEDIA_BAD_FORMAT:
247 			return "Bad media format";
248 		case B_MEDIA_BAD_BUFFER:
249 			return "Bad buffer";
250 		case B_MEDIA_TOO_MANY_NODES:
251 			return "Too many nodes";
252 		case B_MEDIA_TOO_MANY_BUFFERS:
253 			return "Too many buffers";
254 		case B_MEDIA_NODE_ALREADY_EXISTS:
255 			return "Media node already exists";
256 		case B_MEDIA_BUFFER_ALREADY_EXISTS:
257 			return "Buffer already exists";
258 		case B_MEDIA_CANNOT_SEEK:
259 			return "Cannot seek";
260 		case B_MEDIA_CANNOT_CHANGE_RUN_MODE:
261 			return "Cannot change run mode";
262 		case B_MEDIA_APP_ALREADY_REGISTERED:
263 			return "Application already registered";
264 		case B_MEDIA_APP_NOT_REGISTERED:
265 			return "Application not registered";
266 		case B_MEDIA_CANNOT_RECLAIM_BUFFERS:
267 			return "Cannot reclaim buffers";
268 		case B_MEDIA_BUFFERS_NOT_RECLAIMED:
269 			return "Buffers not reclaimed";
270 		case B_MEDIA_TIME_SOURCE_STOPPED:
271 			return "Time source stopped";
272 		case B_MEDIA_TIME_SOURCE_BUSY:
273 			return "Time source busy";
274 		case B_MEDIA_BAD_SOURCE:
275 			return "Bad source";
276 		case B_MEDIA_BAD_DESTINATION:
277 			return "Bad destination";
278 		case B_MEDIA_ALREADY_CONNECTED:
279 			return "Already connected";
280 		case B_MEDIA_NOT_CONNECTED:
281 			return "Not connected";
282 		case B_MEDIA_BAD_CLIP_FORMAT:
283 			return "Bad clipping format";
284 		case B_MEDIA_ADDON_FAILED:
285 			return "Media addon failed";
286 		case B_MEDIA_ADDON_DISABLED:
287 			return "Media addon disabled";
288 		case B_MEDIA_CHANGE_IN_PROGRESS:
289 			return "Change in progress";
290 		case B_MEDIA_STALE_CHANGE_COUNT:
291 			return "Stale change count";
292 		case B_MEDIA_ADDON_RESTRICTED:
293 			return "Media addon restricted";
294 		case B_MEDIA_NO_HANDLER:
295 			return "No handler";
296 		case B_MEDIA_DUPLICATE_FORMAT:
297 			return "Duplicate format";
298 		case B_MEDIA_REALTIME_DISABLED:
299 			return "Realtime disabled";
300 		case B_MEDIA_REALTIME_UNAVAILABLE:
301 			return "Realtime unavailable";
302 
303 		// Mail Kit Errors
304 
305 		case B_MAIL_NO_DAEMON:
306 			return "No mail daemon";
307 		case B_MAIL_UNKNOWN_USER:
308 			return "Unknown mail user";
309 		case B_MAIL_WRONG_PASSWORD:
310 			return "Wrong password (mail)";
311 		case B_MAIL_UNKNOWN_HOST:
312 			return "Mail unknown host";
313 		case B_MAIL_ACCESS_ERROR:
314 			return "Mail access error";
315 		case B_MAIL_UNKNOWN_FIELD:
316 			return "Unknown mail field";
317 		case B_MAIL_NO_RECIPIENT:
318 			return "No mail recipient";
319 		case B_MAIL_INVALID_MAIL:
320 			return "Invalid mail";
321 
322 		// Printing Errors
323 
324 		case B_NO_PRINT_SERVER:
325 			return "No print server";
326 
327 		// Device Kit Errors
328 
329 		case B_DEV_INVALID_IOCTL:
330 			return "Invalid device ioctl";
331 		case B_DEV_NO_MEMORY:
332 			return "No device memory";
333 		case B_DEV_BAD_DRIVE_NUM:
334 			return "Bad drive number";
335 		case B_DEV_NO_MEDIA:
336 			return "No media present";
337 		case B_DEV_UNREADABLE:
338 			return "Device unreadable";
339 		case B_DEV_FORMAT_ERROR:
340 			return "Device format error";
341 		case B_DEV_TIMEOUT:
342 			return "Device timeout";
343 		case B_DEV_RECALIBRATE_ERROR:
344 			return "Device recalibrate error";
345 		case B_DEV_SEEK_ERROR:
346 			return "Device seek error";
347 		case B_DEV_ID_ERROR:
348 			return "Device ID error";
349 		case B_DEV_READ_ERROR:
350 			return "Device read error";
351 		case B_DEV_WRITE_ERROR:
352 			return "Device write error";
353 		case B_DEV_NOT_READY:
354 			return "Device not ready";
355 		case B_DEV_MEDIA_CHANGED:
356 			return "Device media changed";
357 		case B_DEV_MEDIA_CHANGE_REQUESTED:
358 			return "Device media change requested";
359 		case B_DEV_RESOURCE_CONFLICT:
360 			return "Resource conflict";
361 		case B_DEV_CONFIGURATION_ERROR:
362 			return "Configuration error";
363 		case B_DEV_DISABLED_BY_USER:
364 			return "Disabled by user";
365 		case B_DEV_DOOR_OPEN:
366 			return "Drive door open";
367 
368 		// the commented out ones are really strange error codes...
369 		//case B_DEV_INVALID_PIPE:
370 
371 		case B_DEV_CRC_ERROR:
372 			return "Device check-sum error";
373 		case B_DEV_STALLED:
374 			return "Device stalled";
375 
376 		//case B_DEV_BAD_PID:
377 		//case B_DEV_UNEXPECTED_PID:
378 
379 		case B_DEV_DATA_OVERRUN:
380 			return "Device data overrun";
381 		case B_DEV_DATA_UNDERRUN:
382 			return "Device data underrun";
383 		case B_DEV_FIFO_OVERRUN:
384 			return "Device FIFO overrun";
385 		case B_DEV_FIFO_UNDERRUN:
386 			return "Device FIFO underrun";
387 		case B_DEV_PENDING:
388 			return "Device pending";
389 		case B_DEV_MULTIPLE_ERRORS:
390 			return "Multiple device errors";
391 		case B_DEV_TOO_LATE:
392 			return "Device too late";
393 
394 		// Translation Kit Errors
395 
396 		case B_NO_TRANSLATOR:
397 			return "No translator found";
398 		case B_ILLEGAL_DATA:
399 			return "Illegal data";
400 
401 		// Other POSIX Errors
402 
403 		case ENFILE:
404 			return "File table overflow";
405 		case ENXIO:
406 			return "Device not accessible";
407 		case ESPIPE:
408 			return "Seek not allowed on file descriptor";
409 		case ENOSYS:
410 			return "Function not implemented";
411 		case EDOM:
412 			return "Numerical argument out of range";	// "Domain Error"
413 		case ENOBUFS:
414 			return "No buffer space available";
415 		case E2BIG:
416 			return "Argument too big";
417 		case ECHILD:
418 			return "No child process";
419 		case EDEADLK:
420 			return "Resource deadlock";
421 		case EFBIG:
422 			return "File too large";
423 		case EMLINK:
424 			return "Too many links";
425 		case ENODEV:
426 			return "No such device";
427 		case ENOLCK:
428 			return "No record locks available";
429 		case ENOTTY:
430 			return "Not a tty";
431 		case ESRCH:
432 			return "No such process";
433 		case EFPOS:
434 			return "File Position Error";
435 		case ESIGPARM:
436 			return "Signal Error";
437 		case ERANGE:
438 			return "Range Error";
439 
440 		case EPROTOTYPE:
441 			return "Protocol wrong type for socket";
442 		case EPROTONOSUPPORT:
443 			return "Protocol not supported";
444 		case EPFNOSUPPORT:
445 			return "Protocol family not supported";
446 		case EAFNOSUPPORT:
447 			return "Address family not supported by protocol family";
448 		case EADDRINUSE:
449 			return "Address already in use";
450 		case EADDRNOTAVAIL:
451 			return "Can't assign requested address";
452 		case ENETDOWN:
453 			return "Network is down";
454 		case ENETUNREACH:
455 			return "Network is unreachable";
456 		case ENETRESET:
457 			return "Network dropped connection on reset";
458 		case ECONNABORTED:
459 			return "Software caused connection abort";
460 		case ECONNRESET:
461 			return "Connection reset by peer";
462 		case EISCONN:
463 			return "Socket is already connected";
464 		case ENOTCONN:
465 			return "Socket is not connected";
466 		case ESHUTDOWN:
467 			return "Can't send after socket shutdown";
468 		case ECONNREFUSED:
469 			return "Connection refused";
470 		case EHOSTUNREACH:
471 			return "No route to host";
472 		case ENOPROTOOPT:
473 			return "Protocol option not available";
474 		case EINPROGRESS:
475 			return "Operation now in progress";
476 		case EALREADY:
477 			return "Operation already in progress";
478 		case EILSEQ:
479 			return "Illegal byte sequence";
480 		case ENOMSG:
481 			return "No message of desired type";
482 		case ESTALE:
483 			return "Stale file handle";
484 
485 		case EOVERFLOW:
486 			return "Value too large for defined type";
487 		case EMSGSIZE:
488 			return "Message too long";
489 		case EOPNOTSUPP:
490 			return "Operation not supported";
491 		case ENOTSOCK:
492 			return "Socket operation on non-socket";
493 		case EBADMSG:
494 			return "Bad message";
495 		case ECANCELED:
496 			return "Operation canceled";
497 		case EDESTADDRREQ:
498 			return "Destination address required";
499 		case EDQUOT:
500 			return "Reserved";
501 		case EIDRM:
502 			return "Identifier removed";
503 		case EMULTIHOP:
504 			return "Reserved";
505 		case ENODATA:
506 			return "No message available";
507 		case ENOLINK:
508 			return "Reserved";
509 		case ENOSR:
510 			return "No STREAM resources";
511 		case ENOSTR:
512 			return "Not a STREAM";
513 		case ENOTSUP:
514 			return "Not supported";
515 		case EPROTO:
516 			return "Protocol error";
517 		case ETIME:
518 			return "STREAM ioctl() timeout";
519 		case ETXTBSY:
520 			return "Text file busy";
521 		case ENOATTR:
522 			return "No such attribute";
523 
524 		default:
525 			return NULL;
526 	}
527 }
528 
529 
530 char *
531 strerror(int error)
532 {
533 	static char unknown[48];
534 	uint32 i;
535 
536 	char *description = error_description(error);
537 	if (description != NULL)
538 		return description;
539 
540 	if (error < B_OK) {
541 		const char *system = "";
542 		for (i = 0; i < kNumErrorBases; i++) {
543 			if (kErrorBases[i].base <= error
544 				&& ((i + 1 < kNumErrorBases && kErrorBases[i + 1].base > error)
545 					|| i + 1 == kNumErrorBases)) {
546 				system = kErrorBases[i].name;
547 				break;
548 			}
549 		}
550 		sprintf(unknown, "Unknown %sError (%d)", system, error);
551 	} else
552 		sprintf(unknown, "No Error (%d)", error);
553 
554 	return unknown;
555 }
556 
557 
558 int
559 strerror_r(int error, char *buffer, size_t bufferSize)
560 {
561 	char *description = error_description(error);
562 	if (description == NULL)
563 		return EINVAL;
564 
565 	strlcpy(buffer, description, bufferSize);
566 	return 0;
567 		// TODO: could return ERANGE if buffer is too small
568 }
569 
570