| 1 |
// Copyright (c) 2009, Whispersoft s.r.l. |
|---|
| 2 |
// All rights reserved. |
|---|
| 3 |
// |
|---|
| 4 |
// Redistribution and use in source and binary forms, with or without |
|---|
| 5 |
// modification, are permitted provided that the following conditions are |
|---|
| 6 |
// met: |
|---|
| 7 |
// |
|---|
| 8 |
// * Redistributions of source code must retain the above copyright |
|---|
| 9 |
// notice, this list of conditions and the following disclaimer. |
|---|
| 10 |
// * Redistributions in binary form must reproduce the above |
|---|
| 11 |
// copyright notice, this list of conditions and the following disclaimer |
|---|
| 12 |
// in the documentation and/or other materials provided with the |
|---|
| 13 |
// distribution. |
|---|
| 14 |
// * Neither the name of Whispersoft s.r.l. nor the names of its |
|---|
| 15 |
// contributors may be used to endorse or promote products derived from |
|---|
| 16 |
// this software without specific prior written permission. |
|---|
| 17 |
// |
|---|
| 18 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|---|
| 19 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|---|
| 20 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|---|
| 21 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|---|
| 22 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|---|
| 23 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|---|
| 24 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|---|
| 25 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|---|
| 26 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|---|
| 27 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|---|
| 28 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|---|
| 29 |
// |
|---|
| 30 |
// Author: Cosmin Tudorache |
|---|
| 31 |
|
|---|
| 32 |
#include <string.h> |
|---|
| 33 |
#include <errno.h> |
|---|
| 34 |
|
|---|
| 35 |
#include "common/base/errno.h" |
|---|
| 36 |
|
|---|
| 37 |
extern int errno; |
|---|
| 38 |
|
|---|
| 39 |
#define ESUCCESS 0 |
|---|
| 40 |
// One annoying feature of the POSIX 1003.1 specification is the lack of a |
|---|
| 41 |
// no error value. When errno is set to 0, you've encountered no problems, |
|---|
| 42 |
// except you can't refer to this with a standard symbolic constant. |
|---|
| 43 |
|
|---|
| 44 |
int GetLastSystemError() { |
|---|
| 45 |
return errno; |
|---|
| 46 |
} |
|---|
| 47 |
|
|---|
| 48 |
void SetLastSystemError(int err) { |
|---|
| 49 |
errno = err; |
|---|
| 50 |
} |
|---|
| 51 |
|
|---|
| 52 |
#define STRINGISIZE(x) #x |
|---|
| 53 |
#define ERROR_NO(x) "[" #x " " STRINGISIZE(x) "] " |
|---|
| 54 |
|
|---|
| 55 |
const char* GetSystemErrorDescription(int sys_err) { |
|---|
| 56 |
switch ( sys_err ) { |
|---|
| 57 |
case ESUCCESS: |
|---|
| 58 |
return ERROR_NO(ESUCCESS) "No error"; |
|---|
| 59 |
case EPERM: |
|---|
| 60 |
return ERROR_NO(EPERM) "Operation not permitted"; |
|---|
| 61 |
case ENOENT: |
|---|
| 62 |
return ERROR_NO(ENOENT) "No such file or directory"; |
|---|
| 63 |
case ESRCH: |
|---|
| 64 |
return ERROR_NO(ESRCH) "No such process"; |
|---|
| 65 |
case EINTR: |
|---|
| 66 |
return ERROR_NO(EINTR) "Interrupted system call"; |
|---|
| 67 |
case EIO: |
|---|
| 68 |
return ERROR_NO(EIO) "I/O error"; |
|---|
| 69 |
case ENXIO: |
|---|
| 70 |
return ERROR_NO(ENXIO) "No such device or address"; |
|---|
| 71 |
case E2BIG: |
|---|
| 72 |
return ERROR_NO(E2BIG) "Argument list too long"; |
|---|
| 73 |
case ENOEXEC: |
|---|
| 74 |
return ERROR_NO(ENOEXEC) "Exec format error"; |
|---|
| 75 |
case EBADF: |
|---|
| 76 |
return ERROR_NO(EBADF) "Bad file number"; |
|---|
| 77 |
case ECHILD: |
|---|
| 78 |
return ERROR_NO(ECHILD) "No child processes"; |
|---|
| 79 |
case EAGAIN: |
|---|
| 80 |
return ERROR_NO(EAGAIN) "Try again"; |
|---|
| 81 |
case ENOMEM: |
|---|
| 82 |
return ERROR_NO(ENOMEM) "Out of memory"; |
|---|
| 83 |
case EACCES: |
|---|
| 84 |
return ERROR_NO(EACCES) "Permission denied"; |
|---|
| 85 |
case EFAULT: |
|---|
| 86 |
return ERROR_NO(EFAULT) "Bad address"; |
|---|
| 87 |
case ENOTBLK: |
|---|
| 88 |
return ERROR_NO(ENOTBLK) "Block device required"; |
|---|
| 89 |
case EBUSY: |
|---|
| 90 |
return ERROR_NO(EBUSY) "Device or resource busy"; |
|---|
| 91 |
case EEXIST: |
|---|
| 92 |
return ERROR_NO(EEXIST) "File exists"; |
|---|
| 93 |
case EXDEV: |
|---|
| 94 |
return ERROR_NO(EXDEV) "Cross-device link"; |
|---|
| 95 |
case ENODEV: |
|---|
| 96 |
return ERROR_NO(ENODEV) "No such device"; |
|---|
| 97 |
case ENOTDIR: |
|---|
| 98 |
return ERROR_NO(ENOTDIR) "Not a directory"; |
|---|
| 99 |
case EISDIR: |
|---|
| 100 |
return ERROR_NO(EISDIR) "Is a directory"; |
|---|
| 101 |
case EINVAL: |
|---|
| 102 |
return ERROR_NO(EINVAL) "Invalid argument"; |
|---|
| 103 |
case ENFILE: |
|---|
| 104 |
return ERROR_NO(ENFILE) "File table overflow"; |
|---|
| 105 |
case EMFILE: |
|---|
| 106 |
return ERROR_NO(EMFILE) "Too many open files"; |
|---|
| 107 |
case ENOTTY: |
|---|
| 108 |
return ERROR_NO(ENOTTY) "Not a typewriter"; |
|---|
| 109 |
case ETXTBSY: |
|---|
| 110 |
return ERROR_NO(ETXTBSY) "Text file busy"; |
|---|
| 111 |
case EFBIG: |
|---|
| 112 |
return ERROR_NO(EFBIG) "File too large"; |
|---|
| 113 |
case ENOSPC: |
|---|
| 114 |
return ERROR_NO(ENOSPC) "No space left on device"; |
|---|
| 115 |
case ESPIPE: |
|---|
| 116 |
return ERROR_NO(ESPIPE) "Illegal seek"; |
|---|
| 117 |
case EROFS: |
|---|
| 118 |
return ERROR_NO(EROFS) "Read-only file system"; |
|---|
| 119 |
case EMLINK: |
|---|
| 120 |
return ERROR_NO(EMLINK) "Too many links"; |
|---|
| 121 |
case EPIPE: |
|---|
| 122 |
return ERROR_NO(EPIPE) "Broken pipe"; |
|---|
| 123 |
case EDOM: |
|---|
| 124 |
return ERROR_NO(EDOM) "Math argument out of domain of func"; |
|---|
| 125 |
case ERANGE: |
|---|
| 126 |
return ERROR_NO(ERANGE) "Math result not representable"; |
|---|
| 127 |
case EDEADLK: |
|---|
| 128 |
return ERROR_NO(EDEADLK) "Resource deadlock would occur"; |
|---|
| 129 |
case ENAMETOOLONG: |
|---|
| 130 |
return ERROR_NO(ENAMETOOLONG) "File name too long"; |
|---|
| 131 |
case ENOLCK: |
|---|
| 132 |
return ERROR_NO(ENOLCK) "No record locks available"; |
|---|
| 133 |
case ENOSYS: |
|---|
| 134 |
return ERROR_NO(ENOSYS) "Function not implemented"; |
|---|
| 135 |
case ENOTEMPTY: |
|---|
| 136 |
return ERROR_NO(ENOTEMPTY) "Directory not empty"; |
|---|
| 137 |
case ELOOP: |
|---|
| 138 |
return ERROR_NO(ELOOP) "Too many symbolic links encountered"; |
|---|
| 139 |
// #define EWOULDBLOCK EAGAIN // Operation would block |
|---|
| 140 |
case ENOMSG: |
|---|
| 141 |
return ERROR_NO(ENOMSG) "No message of desired type"; |
|---|
| 142 |
case EIDRM: |
|---|
| 143 |
return ERROR_NO(EIDRM) "Identifier removed"; |
|---|
| 144 |
case ECHRNG: |
|---|
| 145 |
return ERROR_NO(ECHRNG) "Channel number out of range"; |
|---|
| 146 |
case EL2NSYNC: |
|---|
| 147 |
return ERROR_NO(EL2NSYNC) "Level 2 not synchronized"; |
|---|
| 148 |
case EL3HLT: |
|---|
| 149 |
return ERROR_NO(EL3HLT) "Level 3 halted"; |
|---|
| 150 |
case EL3RST: |
|---|
| 151 |
return ERROR_NO(EL3RST) "Level 3 reset"; |
|---|
| 152 |
case ELNRNG: |
|---|
| 153 |
return ERROR_NO(ELNRNG) "Link number out of range"; |
|---|
| 154 |
case EUNATCH: |
|---|
| 155 |
return ERROR_NO(EUNATCH) "Protocol driver not attached"; |
|---|
| 156 |
case ENOCSI: |
|---|
| 157 |
return ERROR_NO(ENOCSI) "No CSI structure available"; |
|---|
| 158 |
case EL2HLT: |
|---|
| 159 |
return ERROR_NO(EL2HLT) "Level 2 halted"; |
|---|
| 160 |
case EBADE: |
|---|
| 161 |
return ERROR_NO(EBADE) "Invalid exchange"; |
|---|
| 162 |
case EBADR: |
|---|
| 163 |
return ERROR_NO(EBADR) "Invalid request descriptor"; |
|---|
| 164 |
case EXFULL: |
|---|
| 165 |
return ERROR_NO(EXFULL) "Exchange full"; |
|---|
| 166 |
case ENOANO: |
|---|
| 167 |
return ERROR_NO(ENOANO) "No anode"; |
|---|
| 168 |
case EBADRQC: |
|---|
| 169 |
return ERROR_NO(EBADRQC) "Invalid request code"; |
|---|
| 170 |
case EBADSLT: |
|---|
| 171 |
return ERROR_NO(EBADSLT) "Invalid slot"; |
|---|
| 172 |
// #define EDEADLOCK EDEADLK |
|---|
| 173 |
case EBFONT: |
|---|
| 174 |
return ERROR_NO(EBFONT) "Bad font file format"; |
|---|
| 175 |
case ENOSTR: |
|---|
| 176 |
return ERROR_NO(ENOSTR) "Device not a stream"; |
|---|
| 177 |
case ENODATA: |
|---|
| 178 |
return ERROR_NO(ENODATA) "No data available"; |
|---|
| 179 |
case ETIME: |
|---|
| 180 |
return ERROR_NO(ETIME) "Timer expired"; |
|---|
| 181 |
case ENOSR: |
|---|
| 182 |
return ERROR_NO(ENOSR) "Out of streams resources"; |
|---|
| 183 |
case ENONET: |
|---|
| 184 |
return ERROR_NO(ENONET) "Machine is not on the network"; |
|---|
| 185 |
case ENOPKG: |
|---|
| 186 |
return ERROR_NO(ENOPKG) "Package not installed"; |
|---|
| 187 |
case EREMOTE: |
|---|
| 188 |
return ERROR_NO(EREMOTE) "Object is remote"; |
|---|
| 189 |
case ENOLINK: |
|---|
| 190 |
return ERROR_NO(ENOLINK) "Link has been severed"; |
|---|
| 191 |
case EADV: |
|---|
| 192 |
return ERROR_NO(EADV) "Advertise error"; |
|---|
| 193 |
case ESRMNT: |
|---|
| 194 |
return ERROR_NO(ESRMNT) "Srmount error"; |
|---|
| 195 |
case ECOMM: |
|---|
| 196 |
return ERROR_NO(ECOMM) "Communication error on send"; |
|---|
| 197 |
case EPROTO: |
|---|
| 198 |
return ERROR_NO(EPROTO) "Protocol error"; |
|---|
| 199 |
case EMULTIHOP: |
|---|
| 200 |
return ERROR_NO(EMULTIHOP) "Multihop attempted"; |
|---|
| 201 |
case EDOTDOT: |
|---|
| 202 |
return ERROR_NO(EDOTDOT) "RFS specific error"; |
|---|
| 203 |
case EBADMSG: |
|---|
| 204 |
return ERROR_NO(EBADMSG) "Not a data message"; |
|---|
| 205 |
case EOVERFLOW: |
|---|
| 206 |
return ERROR_NO(EOVERFLOW) "Value too large for defined data type"; |
|---|
| 207 |
case ENOTUNIQ: |
|---|
| 208 |
return ERROR_NO(ENOTUNIQ) "Name not unique on network"; |
|---|
| 209 |
case EBADFD: |
|---|
| 210 |
return ERROR_NO(EBADFD) "File descriptor in bad state"; |
|---|
| 211 |
case EREMCHG: |
|---|
| 212 |
return ERROR_NO(EREMCHG) "Remote address changed"; |
|---|
| 213 |
case ELIBACC: |
|---|
| 214 |
return ERROR_NO(ELIBACC) "Can not access a needed shared library"; |
|---|
| 215 |
case ELIBBAD: |
|---|
| 216 |
return ERROR_NO(ELIBBAD) "Accessing a corrupted shared library"; |
|---|
| 217 |
case ELIBSCN: |
|---|
| 218 |
return ERROR_NO(ELIBSCN) ".lib section in a.out corrupted"; |
|---|
| 219 |
case ELIBMAX: |
|---|
| 220 |
return ERROR_NO(ELIBMAX) "Attempting to link in too many shared libraries"; |
|---|
| 221 |
case ELIBEXEC: |
|---|
| 222 |
return ERROR_NO(ELIBEXEC) "Cannot exec a shared library directly"; |
|---|
| 223 |
case EILSEQ: |
|---|
| 224 |
return ERROR_NO(EILSEQ) "Illegal byte sequence"; |
|---|
| 225 |
case ERESTART: |
|---|
| 226 |
return ERROR_NO(ERESTART) "Interrupted system call should be restarted"; |
|---|
| 227 |
case ESTRPIPE: |
|---|
| 228 |
return ERROR_NO(ESTRPIPE) "Streams pipe error"; |
|---|
| 229 |
case EUSERS: |
|---|
| 230 |
return ERROR_NO(EUSERS) "Too many users"; |
|---|
| 231 |
case ENOTSOCK: |
|---|
| 232 |
return ERROR_NO(ENOTSOCK) "Socket operation on non-socket"; |
|---|
| 233 |
case EDESTADDRREQ: |
|---|
| 234 |
return ERROR_NO(EDESTADDRREQ) "Destination address required"; |
|---|
| 235 |
case EMSGSIZE: |
|---|
| 236 |
return ERROR_NO(EMSGSIZE) "Message too long"; |
|---|
| 237 |
case EPROTOTYPE: |
|---|
| 238 |
return ERROR_NO(EPROTOTYPE) "Protocol wrong type for socket"; |
|---|
| 239 |
case ENOPROTOOPT: |
|---|
| 240 |
return ERROR_NO(ENOPROTOOPT) "Protocol not available"; |
|---|
| 241 |
case EPROTONOSUPPORT: |
|---|
| 242 |
return ERROR_NO(EPROTONOSUPPORT) "Protocol not supported"; |
|---|
| 243 |
case ESOCKTNOSUPPORT: |
|---|
| 244 |
return ERROR_NO(ESOCKTNOSUPPORT) "Socket type not supported"; |
|---|
| 245 |
case EOPNOTSUPP: |
|---|
| 246 |
return ERROR_NO(EOPNOTSUPP) "Operation not supported on transport endpoint"; |
|---|
| 247 |
case EPFNOSUPPORT: |
|---|
| 248 |
return ERROR_NO(EPFNOSUPPORT) "Protocol family not supported"; |
|---|
| 249 |
case EAFNOSUPPORT: |
|---|
| 250 |
return ERROR_NO(EAFNOSUPPORT) "Address family not supported by protocol"; |
|---|
| 251 |
case EADDRINUSE: |
|---|
| 252 |
return ERROR_NO(EADDRINUSE) "Address already in use"; |
|---|
| 253 |
case EADDRNOTAVAIL: |
|---|
| 254 |
return ERROR_NO(EADDRNOTAVAIL) "Cannot assign requested address"; |
|---|
| 255 |
case ENETDOWN: |
|---|
| 256 |
return ERROR_NO(ENETDOWN) "Network is down"; |
|---|
| 257 |
case ENETUNREACH: |
|---|
| 258 |
return ERROR_NO(ENETUNREACH) "Network is unreachable"; |
|---|
| 259 |
case ENETRESET: |
|---|
| 260 |
return ERROR_NO(ENETRESET) "Network dropped connection because of reset"; |
|---|
| 261 |
case ECONNABORTED: |
|---|
| 262 |
return ERROR_NO(ECONNABORTED) "Software caused connection abort"; |
|---|
| 263 |
case ECONNRESET: |
|---|
| 264 |
return ERROR_NO(ECONNRESET) "Connection reset by peer"; |
|---|
| 265 |
case ENOBUFS: |
|---|
| 266 |
return ERROR_NO(ENOBUFS) "No buffer space available"; |
|---|
| 267 |
case EISCONN: |
|---|
| 268 |
return ERROR_NO(EISCONN) "Transport endpoint is already connected"; |
|---|
| 269 |
case ENOTCONN: |
|---|
| 270 |
return ERROR_NO(ENOTCONN) "Transport endpoint is not connected"; |
|---|
| 271 |
case ESHUTDOWN: |
|---|
| 272 |
return ERROR_NO(ESHUTDOWN) "Cannot send after transport endpoint shutdown"; |
|---|
| 273 |
case ETOOMANYREFS: |
|---|
| 274 |
return ERROR_NO(ETOOMANYREFS) "Too many references: cannot splice"; |
|---|
| 275 |
case ETIMEDOUT: |
|---|
| 276 |
return ERROR_NO(ETIMEDOUT) "Connection timed out"; |
|---|
| 277 |
case ECONNREFUSED: |
|---|
| 278 |
return ERROR_NO(ECONNREFUSED) "Connection refused"; |
|---|
| 279 |
case EHOSTDOWN: |
|---|
| 280 |
return ERROR_NO(EHOSTDOWN) "Host is down"; |
|---|
| 281 |
case EHOSTUNREACH: |
|---|
| 282 |
return ERROR_NO(EHOSTUNREACH) "No route to host"; |
|---|
| 283 |
case EALREADY: |
|---|
| 284 |
return ERROR_NO(EALREADY) "Operation already in progress"; |
|---|
| 285 |
case EINPROGRESS: |
|---|
| 286 |
return ERROR_NO(EINPROGRESS) "Operation now in progress"; |
|---|
| 287 |
case ESTALE: |
|---|
| 288 |
return ERROR_NO(ESTALE) "Stale NFS file handle"; |
|---|
| 289 |
case EUCLEAN: |
|---|
| 290 |
return ERROR_NO(EUCLEAN) "Structure needs cleaning"; |
|---|
| 291 |
case ENOTNAM: |
|---|
| 292 |
return ERROR_NO(ENOTNAM) "Not a XENIX named type file"; |
|---|
| 293 |
case ENAVAIL: |
|---|
| 294 |
return ERROR_NO(ENAVAIL) "No XENIX semaphores available"; |
|---|
| 295 |
case EISNAM: |
|---|
| 296 |
return ERROR_NO(EISNAM) "Is a named type file"; |
|---|
| 297 |
case EREMOTEIO: |
|---|
| 298 |
return ERROR_NO(EREMOTEIO) "Remote I/O error"; |
|---|
| 299 |
case EDQUOT: |
|---|
| 300 |
return ERROR_NO(EDQUOT) "Quota exceeded"; |
|---|
| 301 |
case ENOMEDIUM: |
|---|
| 302 |
return ERROR_NO(ENOMEDIUM) "No medium found"; |
|---|
| 303 |
case EMEDIUMTYPE: |
|---|
| 304 |
return ERROR_NO(EMEDIUMTYPE) "Wrong medium type"; |
|---|
| 305 |
case ECANCELED: |
|---|
| 306 |
return ERROR_NO(ECANCELED) "Operation Canceled"; |
|---|
| 307 |
case ENOKEY: |
|---|
| 308 |
return ERROR_NO(ENOKEY) "Required key not available"; |
|---|
| 309 |
case EKEYEXPIRED: |
|---|
| 310 |
return ERROR_NO(EKEYEXPIRED) "Key has expired"; |
|---|
| 311 |
case EKEYREVOKED: |
|---|
| 312 |
return ERROR_NO(EKEYREVOKED) "Key has been revoked"; |
|---|
| 313 |
case EKEYREJECTED: |
|---|
| 314 |
return ERROR_NO(EKEYREJECTED) "Key was rejected by service"; |
|---|
| 315 |
// for robust mutexes |
|---|
| 316 |
case EOWNERDEAD: |
|---|
| 317 |
return ERROR_NO(EOWNERDEAD) "Owner died"; |
|---|
| 318 |
case ENOTRECOVERABLE: |
|---|
| 319 |
return ERROR_NO(ENOTRECOVERABLE) "State not recoverable"; |
|---|
| 320 |
} |
|---|
| 321 |
return "Unknown error"; |
|---|
| 322 |
} |
|---|
| 323 |
|
|---|
| 324 |
const char* GetLastSystemErrorDescription() { |
|---|
| 325 |
return GetSystemErrorDescription(GetLastSystemError()); |
|---|
| 326 |
} |
|---|