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 ADD_ERROR(EPFNOSUPPORT); 53 ADD_ERROR(EAFNOSUPPORT); 54 ADD_ERROR(EADDRINUSE); 55 ADD_ERROR(EADDRNOTAVAIL); 56 ADD_ERROR(ENETDOWN); 57 ADD_ERROR(ENETUNREACH); 58 ADD_ERROR(ENETRESET); 59 ADD_ERROR(ECONNABORTED); 60 ADD_ERROR(ECONNRESET); 61 ADD_ERROR(EISCONN); 62 ADD_ERROR(ENOTCONN); 63 ADD_ERROR(ESHUTDOWN); 64 ADD_ERROR(ECONNREFUSED); 65 ADD_ERROR(EHOSTUNREACH); 66 ADD_ERROR(ENOPROTOOPT); 67 ADD_ERROR(ENOBUFS); 68 ADD_ERROR(EINPROGRESS); 69 ADD_ERROR(EALREADY); 70 ADD_ERROR(EILSEQ); 71 ADD_ERROR(ENOMSG); 72 ADD_ERROR(ESTALE); 73 ADD_ERROR(EOVERFLOW); 74 ADD_ERROR(EMSGSIZE); 75 ADD_ERROR(EOPNOTSUPP); 76 ADD_ERROR(ENOTSOCK); 77 ADD_ERROR(EHOSTDOWN); 78 ADD_ERROR(EBADMSG); 79 #ifdef ECANCELED 80 ADD_ERROR(ECANCELED); 81 #endif 82 ADD_ERROR(EDESTADDRREQ); 83 ADD_ERROR(EDQUOT); 84 ADD_ERROR(EIDRM); 85 ADD_ERROR(EMULTIHOP); 86 #ifdef ENODATA 87 ADD_ERROR(ENODATA); 88 #endif 89 ADD_ERROR(ENOLINK); 90 #ifdef ENOSR 91 ADD_ERROR(ENOSR); 92 #endif 93 #ifdef ENOSTR 94 ADD_ERROR(ENOSTR); 95 #endif 96 ADD_ERROR(ENOTSUP); 97 ADD_ERROR(EPROTO); 98 #ifdef ETIME 99 ADD_ERROR(ETIME); 100 #endif 101 ADD_ERROR(ETXTBSY); 102 ADD_ERROR(ENOMEM); 103 ADD_ERROR(EACCES); 104 ADD_ERROR(EINTR); 105 ADD_ERROR(EIO); 106 ADD_ERROR(EBUSY); 107 ADD_ERROR(EFAULT); 108 ADD_ERROR(ETIMEDOUT); 109 ADD_ERROR(EAGAIN); 110 ADD_ERROR(EWOULDBLOCK); 111 ADD_ERROR(EBADF); 112 ADD_ERROR(EEXIST); 113 ADD_ERROR(EINVAL); 114 ADD_ERROR(ENAMETOOLONG); 115 ADD_ERROR(ENOENT); 116 ADD_ERROR(EPERM); 117 ADD_ERROR(ENOTDIR); 118 ADD_ERROR(EISDIR); 119 ADD_ERROR(ENOTEMPTY); 120 ADD_ERROR(ENOSPC); 121 ADD_ERROR(EROFS); 122 ADD_ERROR(EMFILE); 123 ADD_ERROR(EXDEV); 124 ADD_ERROR(ELOOP); 125 ADD_ERROR(ENOEXEC); 126 ADD_ERROR(EPIPE); 127 #ifdef ENOATTR 128 ADD_ERROR(ENOATTR); 129 #endif 130 131 sErrorMapsInitialized = true; 132 } 133 134 // to_host_error 135 static int 136 to_host_error(int error) 137 { 138 init_error_map(); 139 140 map<int, int>::iterator it = sToHostErrorMap.find(error); 141 return (it != sToHostErrorMap.end() ? it->second : error); 142 } 143 144 // to_haiku_error 145 static int 146 to_haiku_error(int error) 147 { 148 init_error_map(); 149 150 map<int, int>::iterator it = sToHaikuErrorMap.find(error); 151 if (it != sToHaikuErrorMap.end()) 152 return it->second; 153 154 return (error > 0 ? -error : error); 155 } 156 157 // _haiku_build_strerror 158 char * 159 _haiku_build_strerror(int errnum) 160 { 161 return strerror(to_host_error(errnum)); 162 } 163 164 // _haiku_build_errno 165 int * 166 _haiku_build_errno() 167 { 168 static int previousErrno = 0; 169 static int localErrno = 0; 170 static int previousLocalErrno = 0; 171 172 // If the localErrno has been changed and the real errno has not changed 173 // in the meantime, we update errno itself, so that the local update will 174 // be reflected. If errno has changed we always update localErrno. 175 int currentErrno = errno; 176 if (currentErrno == previousErrno) { 177 if (localErrno != previousLocalErrno) { 178 errno = previousErrno = to_host_error(localErrno); 179 previousLocalErrno = localErrno; 180 } 181 } else { 182 previousErrno = currentErrno; 183 previousLocalErrno = localErrno = to_haiku_error(errno); 184 } 185 186 return &localErrno; 187 } 188 189 // _haiku_to_host_error 190 int 191 _haiku_to_host_error(int error) 192 { 193 return to_host_error(error); 194 } 195