xref: /haiku/src/build/libroot/errors.cpp (revision e705c841d784f0035a0ef3e9e96f6e017df16681)
1 /*
2  * Copyright 2005-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <errno.h>
8 #include <string.h>
9 
10 #include <map>
11 
12 using namespace std;
13 
14 static map<int, int> sToHaikuErrorMap;
15 static map<int, int> sToHostErrorMap;
16 static bool sErrorMapsInitialized = false;
17 
18 // init_error_map
19 static void
20 init_error_map()
21 {
22 	if (sErrorMapsInitialized)
23 		return;
24 
25 	#define ADD_ERROR(error) \
26 		sToHaikuErrorMap[error] = HAIKU_##error; \
27 		sToHostErrorMap[HAIKU_##error] = error;
28 
29 	ADD_ERROR(E2BIG);
30 	ADD_ERROR(ECHILD);
31 	ADD_ERROR(EDEADLK);
32 	ADD_ERROR(EFBIG);
33 	ADD_ERROR(EMLINK);
34 	ADD_ERROR(ENFILE);
35 	ADD_ERROR(ENODEV);
36 	ADD_ERROR(ENOLCK);
37 	ADD_ERROR(ENOSYS);
38 	ADD_ERROR(ENOTTY);
39 	ADD_ERROR(ENXIO);
40 	ADD_ERROR(ESPIPE);
41 	ADD_ERROR(ESRCH);
42 	#ifdef EFPOS
43 		ADD_ERROR(EFPOS);
44 	#endif
45 	#ifdef ESIGPARM
46 		ADD_ERROR(ESIGPARM);
47 	#endif
48 	ADD_ERROR(EDOM);
49 	ADD_ERROR(ERANGE);
50 	ADD_ERROR(EPROTOTYPE);
51 	ADD_ERROR(EPROTONOSUPPORT);
52 	#ifdef EPFNOSUPPORT
53 		ADD_ERROR(EPFNOSUPPORT);
54 	#endif
55 	ADD_ERROR(EAFNOSUPPORT);
56 	ADD_ERROR(EADDRINUSE);
57 	ADD_ERROR(EADDRNOTAVAIL);
58 	ADD_ERROR(ENETDOWN);
59 	ADD_ERROR(ENETUNREACH);
60 	ADD_ERROR(ENETRESET);
61 	ADD_ERROR(ECONNABORTED);
62 	ADD_ERROR(ECONNRESET);
63 	ADD_ERROR(EISCONN);
64 	ADD_ERROR(ENOTCONN);
65 	#ifdef ESHUTDOWN
66 		ADD_ERROR(ESHUTDOWN);
67 	#endif
68 	ADD_ERROR(ECONNREFUSED);
69 	ADD_ERROR(EHOSTUNREACH);
70 	ADD_ERROR(ENOPROTOOPT);
71 	ADD_ERROR(ENOBUFS);
72 	ADD_ERROR(EINPROGRESS);
73 	ADD_ERROR(EALREADY);
74 	ADD_ERROR(EILSEQ);
75 	#ifdef ENOMSG
76 		ADD_ERROR(ENOMSG);
77 	#endif
78 	#ifdef ESTALE
79 		ADD_ERROR(ESTALE);
80 	#endif
81 	ADD_ERROR(EOVERFLOW);
82 	ADD_ERROR(EMSGSIZE);
83 	ADD_ERROR(EOPNOTSUPP);
84 	ADD_ERROR(ENOTSOCK);
85 	#ifdef EHOSTDOWN
86 		ADD_ERROR(EHOSTDOWN);
87 	#endif
88 	#ifdef EBADMSG
89 		ADD_ERROR(EBADMSG);
90 	#endif
91 	#ifdef ECANCELED
92 		ADD_ERROR(ECANCELED);
93 	#endif
94 	ADD_ERROR(EDESTADDRREQ);
95 	#ifdef EDQUOT
96 		ADD_ERROR(EDQUOT);
97 	#endif
98 	#ifdef EIDRM
99 		ADD_ERROR(EIDRM);
100 	#endif
101 	#ifdef EMULTIHOP
102 		ADD_ERROR(EMULTIHOP);
103 	#endif
104 	#ifdef ENODATA
105 		ADD_ERROR(ENODATA);
106 	#endif
107 	#ifdef ENOLINK
108 		ADD_ERROR(ENOLINK);
109 	#endif
110 	#ifdef ENOSR
111 		ADD_ERROR(ENOSR);
112 	#endif
113 	#ifdef ENOSTR
114 		ADD_ERROR(ENOSTR);
115 	#endif
116 	ADD_ERROR(ENOTSUP);
117 	ADD_ERROR(EPROTO);
118 	#ifdef ETIME
119 		ADD_ERROR(ETIME);
120 	#endif
121 	#ifdef ETXTBSY
122 		ADD_ERROR(ETXTBSY);
123 	#endif
124 	ADD_ERROR(ENOMEM);
125 	ADD_ERROR(EACCES);
126 	ADD_ERROR(EINTR);
127 	ADD_ERROR(EIO);
128 	ADD_ERROR(EBUSY);
129 	ADD_ERROR(EFAULT);
130 	ADD_ERROR(ETIMEDOUT);
131 	ADD_ERROR(EAGAIN);
132 	ADD_ERROR(EWOULDBLOCK);
133 	ADD_ERROR(EBADF);
134 	ADD_ERROR(EEXIST);
135 	ADD_ERROR(EINVAL);
136 	ADD_ERROR(ENAMETOOLONG);
137 	ADD_ERROR(ENOENT);
138 	ADD_ERROR(EPERM);
139 	ADD_ERROR(ENOTDIR);
140 	ADD_ERROR(EISDIR);
141 	ADD_ERROR(ENOTEMPTY);
142 	ADD_ERROR(ENOSPC);
143 	ADD_ERROR(EROFS);
144 	ADD_ERROR(EMFILE);
145 	ADD_ERROR(EXDEV);
146 	ADD_ERROR(ELOOP);
147 	ADD_ERROR(ENOEXEC);
148 	ADD_ERROR(EPIPE);
149 	#ifdef ENOATTR
150 		ADD_ERROR(ENOATTR);
151 	#endif
152 
153 	sErrorMapsInitialized = true;
154 }
155 
156 // to_host_error
157 static int
158 to_host_error(int error)
159 {
160 	init_error_map();
161 
162 	map<int, int>::iterator it = sToHostErrorMap.find(error);
163 	return (it != sToHostErrorMap.end() ? it->second : error);
164 }
165 
166 // to_haiku_error
167 static int
168 to_haiku_error(int error)
169 {
170 	init_error_map();
171 
172 	map<int, int>::iterator it = sToHaikuErrorMap.find(error);
173 	if (it != sToHaikuErrorMap.end())
174 		return it->second;
175 
176 	return (error > 0 ? -error : error);
177 }
178 
179 // _haiku_build_strerror
180 char *
181 _haiku_build_strerror(int errnum)
182 {
183 	return strerror(to_host_error(errnum));
184 }
185 
186 // _haiku_build_errno
187 int *
188 _haiku_build_errno()
189 {
190 	static int previousErrno = 0;
191 	static int localErrno = 0;
192 	static int previousLocalErrno = 0;
193 
194 	// If the localErrno has been changed and the real errno has not changed
195 	// in the meantime, we update errno itself, so that the local update will
196 	// be reflected. If errno has changed we always update localErrno.
197 	int currentErrno = errno;
198 	if (currentErrno == previousErrno) {
199 		if (localErrno != previousLocalErrno) {
200 			errno = previousErrno = to_host_error(localErrno);
201 			previousLocalErrno = localErrno;
202 		}
203 	} else {
204 		previousErrno = currentErrno;
205 		previousLocalErrno = localErrno = to_haiku_error(errno);
206 	}
207 
208 	return &localErrno;
209 }
210 
211 // _haiku_to_host_error
212 int
213 _haiku_to_host_error(int error)
214 {
215 	return to_host_error(error);
216 }
217