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