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
16static 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};
34static const uint32 kNumErrorBases = sizeof(kErrorBases)
35	/ sizeof(struct error_base);
36
37
38static char *
39error_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
546char *
547strerror(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
574int
575strerror_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
587char *
588strerror_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