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