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