pal_errno.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. #include "il2cpp-config.h"
  2. #include "pal_platform.h"
  3. #if IL2CPP_USES_POSIX_CLASS_LIBRARY_PAL
  4. #include <errno.h>
  5. extern "C"
  6. {
  7. // Items needed by mscorlib
  8. IL2CPP_EXPORT int32_t SystemNative_ConvertErrorPlatformToPal(int32_t platformErrno);
  9. IL2CPP_EXPORT const char* SystemNative_StrErrorR(int32_t platformErrno, char* buffer, int32_t bufferSize);
  10. IL2CPP_EXPORT int32_t SystemNative_ConvertErrorPalToPlatform(int32_t error);
  11. }
  12. /**
  13. * Error codes returned via ConvertErrno.
  14. *
  15. * Only the names (without the PAL_ prefix) are specified by POSIX.
  16. *
  17. * The values chosen below are simply assigned arbitrarily (originally
  18. * in alphabetical order they appear in the spec, but they can't change so
  19. * add new values to the end!).
  20. *
  21. * Also, the values chosen are deliberately outside the range of
  22. * typical UNIX errnos (small numbers), HRESULTs (negative for errors)
  23. * and Win32 errors (0x0000 - 0xFFFF). This isn't required for
  24. * correctness, but may help debug a caller that is interpreting a raw
  25. * int incorrectly.
  26. *
  27. * Wherever the spec says "x may be the same value as y", we do use
  28. * the same value so that callers cannot not take a dependency on
  29. * being able to distinguish between them.
  30. */
  31. enum Error
  32. {
  33. Error_SUCCESS = 0,
  34. Error_E2BIG = 0x10001, // Argument list too long.
  35. Error_EACCES = 0x10002, // Permission denied.
  36. Error_EADDRINUSE = 0x10003, // Address in use.
  37. Error_EADDRNOTAVAIL = 0x10004, // Address not available.
  38. Error_EAFNOSUPPORT = 0x10005, // Address family not supported.
  39. Error_EAGAIN = 0x10006, // Resource unavailable, try again (same value as EWOULDBLOCK),
  40. Error_EALREADY = 0x10007, // Connection already in progress.
  41. Error_EBADF = 0x10008, // Bad file descriptor.
  42. Error_EBADMSG = 0x10009, // Bad message.
  43. Error_EBUSY = 0x1000A, // Device or resource busy.
  44. Error_ECANCELED = 0x1000B, // Operation canceled.
  45. Error_ECHILD = 0x1000C, // No child processes.
  46. Error_ECONNABORTED = 0x1000D, // Connection aborted.
  47. Error_ECONNREFUSED = 0x1000E, // Connection refused.
  48. Error_ECONNRESET = 0x1000F, // Connection reset.
  49. Error_EDEADLK = 0x10010, // Resource deadlock would occur.
  50. Error_EDESTADDRREQ = 0x10011, // Destination address required.
  51. Error_EDOM = 0x10012, // Mathematics argument out of domain of function.
  52. Error_EDQUOT = 0x10013, // Reserved.
  53. Error_EEXIST = 0x10014, // File exists.
  54. Error_EFAULT = 0x10015, // Bad address.
  55. Error_EFBIG = 0x10016, // File too large.
  56. Error_EHOSTUNREACH = 0x10017, // Host is unreachable.
  57. Error_EIDRM = 0x10018, // Identifier removed.
  58. Error_EILSEQ = 0x10019, // Illegal byte sequence.
  59. Error_EINPROGRESS = 0x1001A, // Operation in progress.
  60. Error_EINTR = 0x1001B, // Interrupted function.
  61. Error_EINVAL = 0x1001C, // Invalid argument.
  62. Error_EIO = 0x1001D, // I/O error.
  63. Error_EISCONN = 0x1001E, // Socket is connected.
  64. Error_EISDIR = 0x1001F, // Is a directory.
  65. Error_ELOOP = 0x10020, // Too many levels of symbolic links.
  66. Error_EMFILE = 0x10021, // File descriptor value too large.
  67. Error_EMLINK = 0x10022, // Too many links.
  68. Error_EMSGSIZE = 0x10023, // Message too large.
  69. Error_EMULTIHOP = 0x10024, // Reserved.
  70. Error_ENAMETOOLONG = 0x10025, // Filename too long.
  71. Error_ENETDOWN = 0x10026, // Network is down.
  72. Error_ENETRESET = 0x10027, // Connection aborted by network.
  73. Error_ENETUNREACH = 0x10028, // Network unreachable.
  74. Error_ENFILE = 0x10029, // Too many files open in system.
  75. Error_ENOBUFS = 0x1002A, // No buffer space available.
  76. Error_ENODEV = 0x1002C, // No such device.
  77. Error_ENOENT = 0x1002D, // No such file or directory.
  78. Error_ENOEXEC = 0x1002E, // Executable file format error.
  79. Error_ENOLCK = 0x1002F, // No locks available.
  80. Error_ENOLINK = 0x10030, // Reserved.
  81. Error_ENOMEM = 0x10031, // Not enough space.
  82. Error_ENOMSG = 0x10032, // No message of the desired type.
  83. Error_ENOPROTOOPT = 0x10033, // Protocol not available.
  84. Error_ENOSPC = 0x10034, // No space left on device.
  85. Error_ENOSYS = 0x10037, // Function not supported.
  86. Error_ENOTCONN = 0x10038, // The socket is not connected.
  87. Error_ENOTDIR = 0x10039, // Not a directory or a symbolic link to a directory.
  88. Error_ENOTEMPTY = 0x1003A, // Directory not empty.
  89. Error_ENOTRECOVERABLE = 0x1003B, // State not recoverable.
  90. Error_ENOTSOCK = 0x1003C, // Not a socket.
  91. Error_ENOTSUP = 0x1003D, // Not supported (same value as EOPNOTSUP).
  92. Error_ENOTTY = 0x1003E, // Inappropriate I/O control operation.
  93. Error_ENXIO = 0x1003F, // No such device or address.
  94. Error_EOVERFLOW = 0x10040, // Value too large to be stored in data type.
  95. Error_EOWNERDEAD = 0x10041, // Previous owner died.
  96. Error_EPERM = 0x10042, // Operation not permitted.
  97. Error_EPIPE = 0x10043, // Broken pipe.
  98. Error_EPROTO = 0x10044, // Protocol error.
  99. Error_EPROTONOSUPPORT = 0x10045, // Protocol not supported.
  100. Error_EPROTOTYPE = 0x10046, // Protocol wrong type for socket.
  101. Error_ERANGE = 0x10047, // Result too large.
  102. Error_EROFS = 0x10048, // Read-only file system.
  103. Error_ESPIPE = 0x10049, // Invalid seek.
  104. Error_ESRCH = 0x1004A, // No such process.
  105. Error_ESTALE = 0x1004B, // Reserved.
  106. Error_ETIMEDOUT = 0x1004D, // Connection timed out.
  107. Error_ETXTBSY = 0x1004E, // Text file busy.
  108. Error_EXDEV = 0x1004F, // Cross-device link.
  109. Error_ESOCKTNOSUPPORT = 0x1005E, // Socket type not supported.
  110. Error_EPFNOSUPPORT = 0x10060, // Protocol family not supported.
  111. Error_ESHUTDOWN = 0x1006C, // Socket shutdown.
  112. Error_EHOSTDOWN = 0x10070, // Host is down.
  113. Error_ENODATA = 0x10071, // No data available.
  114. // POSIX permits these to have the same value and we make them
  115. // always equal so that we cannot introduce a dependency on
  116. // distinguishing between them that would not work on all
  117. // platforms.
  118. Error_EOPNOTSUPP = Error_ENOTSUP, // Operation not supported on socket
  119. Error_EWOULDBLOCK = Error_EAGAIN, // Operation would block
  120. // This one is not part of POSIX, but is a catch-all for the case
  121. // where we cannot convert the raw errno value to something above.
  122. Error_ENONSTANDARD = 0x1FFFF,
  123. };
  124. // Items needed by mscorlib
  125. int32_t SystemNative_ConvertErrorPlatformToPal(int32_t platformErrno)
  126. {
  127. switch (platformErrno)
  128. {
  129. case 0:
  130. return Error_SUCCESS;
  131. case E2BIG:
  132. return Error_E2BIG;
  133. case EACCES:
  134. return Error_EACCES;
  135. case EADDRINUSE:
  136. return Error_EADDRINUSE;
  137. case EADDRNOTAVAIL:
  138. return Error_EADDRNOTAVAIL;
  139. case EAFNOSUPPORT:
  140. return Error_EAFNOSUPPORT;
  141. case EAGAIN:
  142. return Error_EAGAIN;
  143. case EALREADY:
  144. return Error_EALREADY;
  145. case EBADF:
  146. return Error_EBADF;
  147. case EBADMSG:
  148. return Error_EBADMSG;
  149. case EBUSY:
  150. return Error_EBUSY;
  151. case ECANCELED:
  152. return Error_ECANCELED;
  153. case ECHILD:
  154. return Error_ECHILD;
  155. case ECONNABORTED:
  156. return Error_ECONNABORTED;
  157. case ECONNREFUSED:
  158. return Error_ECONNREFUSED;
  159. case ECONNRESET:
  160. return Error_ECONNRESET;
  161. case EDEADLK:
  162. return Error_EDEADLK;
  163. case EDESTADDRREQ:
  164. return Error_EDESTADDRREQ;
  165. case EDOM:
  166. return Error_EDOM;
  167. case EDQUOT:
  168. return Error_EDQUOT;
  169. case EEXIST:
  170. return Error_EEXIST;
  171. case EFAULT:
  172. return Error_EFAULT;
  173. case EFBIG:
  174. return Error_EFBIG;
  175. case EHOSTUNREACH:
  176. return Error_EHOSTUNREACH;
  177. case EIDRM:
  178. return Error_EIDRM;
  179. case EILSEQ:
  180. return Error_EILSEQ;
  181. case EINPROGRESS:
  182. return Error_EINPROGRESS;
  183. case EINTR:
  184. return Error_EINTR;
  185. case EINVAL:
  186. return Error_EINVAL;
  187. case EIO:
  188. return Error_EIO;
  189. case EISCONN:
  190. return Error_EISCONN;
  191. case EISDIR:
  192. return Error_EISDIR;
  193. case ELOOP:
  194. return Error_ELOOP;
  195. case EMFILE:
  196. return Error_EMFILE;
  197. case EMLINK:
  198. return Error_EMLINK;
  199. case EMSGSIZE:
  200. return Error_EMSGSIZE;
  201. case EMULTIHOP:
  202. return Error_EMULTIHOP;
  203. case ENAMETOOLONG:
  204. return Error_ENAMETOOLONG;
  205. case ENETDOWN:
  206. return Error_ENETDOWN;
  207. case ENETRESET:
  208. return Error_ENETRESET;
  209. case ENETUNREACH:
  210. return Error_ENETUNREACH;
  211. case ENFILE:
  212. return Error_ENFILE;
  213. case ENOBUFS:
  214. return Error_ENOBUFS;
  215. case ENODEV:
  216. return Error_ENODEV;
  217. case ENOENT:
  218. return Error_ENOENT;
  219. case ENOEXEC:
  220. return Error_ENOEXEC;
  221. case ENOLCK:
  222. return Error_ENOLCK;
  223. case ENOLINK:
  224. return Error_ENOLINK;
  225. case ENOMEM:
  226. return Error_ENOMEM;
  227. case ENOMSG:
  228. return Error_ENOMSG;
  229. case ENOPROTOOPT:
  230. return Error_ENOPROTOOPT;
  231. case ENOSPC:
  232. return Error_ENOSPC;
  233. case ENOSYS:
  234. return Error_ENOSYS;
  235. case ENOTCONN:
  236. return Error_ENOTCONN;
  237. case ENOTDIR:
  238. return Error_ENOTDIR;
  239. #if ENOTEMPTY != EEXIST // AIX defines this
  240. case ENOTEMPTY:
  241. return Error_ENOTEMPTY;
  242. #endif
  243. #ifdef ENOTRECOVERABLE // not available in NetBSD
  244. case ENOTRECOVERABLE:
  245. return Error_ENOTRECOVERABLE;
  246. #endif
  247. case ENOTSOCK:
  248. return Error_ENOTSOCK;
  249. case ENOTSUP:
  250. return Error_ENOTSUP;
  251. case ENOTTY:
  252. return Error_ENOTTY;
  253. case ENXIO:
  254. return Error_ENXIO;
  255. case EOVERFLOW:
  256. return Error_EOVERFLOW;
  257. #ifdef EOWNERDEAD // not available in NetBSD
  258. case EOWNERDEAD:
  259. return Error_EOWNERDEAD;
  260. #endif
  261. case EPERM:
  262. return Error_EPERM;
  263. case EPIPE:
  264. return Error_EPIPE;
  265. case EPROTO:
  266. return Error_EPROTO;
  267. case EPROTONOSUPPORT:
  268. return Error_EPROTONOSUPPORT;
  269. case EPROTOTYPE:
  270. return Error_EPROTOTYPE;
  271. case ERANGE:
  272. return Error_ERANGE;
  273. case EROFS:
  274. return Error_EROFS;
  275. case ESPIPE:
  276. return Error_ESPIPE;
  277. case ESRCH:
  278. return Error_ESRCH;
  279. case ESTALE:
  280. return Error_ESTALE;
  281. case ETIMEDOUT:
  282. return Error_ETIMEDOUT;
  283. case ETXTBSY:
  284. return Error_ETXTBSY;
  285. case EXDEV:
  286. return Error_EXDEV;
  287. #ifdef ESOCKTNOSUPPORT
  288. case ESOCKTNOSUPPORT:
  289. return Error_ESOCKTNOSUPPORT;
  290. #endif
  291. case EPFNOSUPPORT:
  292. return Error_EPFNOSUPPORT;
  293. case ESHUTDOWN:
  294. return Error_ESHUTDOWN;
  295. case EHOSTDOWN:
  296. return Error_EHOSTDOWN;
  297. case ENODATA:
  298. return Error_ENODATA;
  299. // #if because these will trigger duplicate case label warnings when
  300. // they have the same value, which is permitted by POSIX and common.
  301. #if EOPNOTSUPP != ENOTSUP
  302. case EOPNOTSUPP:
  303. return Error_EOPNOTSUPP;
  304. #endif
  305. #if EWOULDBLOCK != EAGAIN
  306. case EWOULDBLOCK:
  307. return Error_EWOULDBLOCK;
  308. #endif
  309. }
  310. return Error_ENONSTANDARD;
  311. }
  312. const char* SystemNative_StrErrorR(int32_t platformErrno, char* buffer, int32_t bufferSize)
  313. {
  314. IL2CPP_ASSERT(buffer != NULL);
  315. IL2CPP_ASSERT(bufferSize > 0);
  316. if (bufferSize < 0)
  317. return NULL;
  318. // Note that we must use strerror_r because plain strerror is not
  319. // thread-safe.
  320. //
  321. // However, there are two versions of strerror_r:
  322. // - GNU: char* strerror_r(int, char*, size_t);
  323. // - POSIX: int strerror_r(int, char*, size_t);
  324. //
  325. // The former may or may not use the supplied buffer, and returns
  326. // the error message string. The latter stores the error message
  327. // string into the supplied buffer and returns an error code.
  328. #if IL2CPP_HAVE_GNU_STRERROR_R
  329. const char* message = strerror_r(platformErrno, buffer, (uint32_t)bufferSize);
  330. IL2CPP_ASSERT(message != NULL);
  331. return message;
  332. #else
  333. int error = strerror_r(platformErrno, buffer, (uint32_t)bufferSize);
  334. if (error == ERANGE)
  335. {
  336. // Buffer is too small to hold the entire message, but has
  337. // still been filled to the extent possible and null-terminated.
  338. return NULL;
  339. }
  340. // The only other valid error codes are 0 for success or EINVAL for
  341. // an unknown error, but in the latter case a reasonable string (e.g
  342. // "Unknown error: 0x123") is returned.
  343. IL2CPP_ASSERT((error == 0 || error == EINVAL) && "invalid error");
  344. return buffer;
  345. #endif
  346. }
  347. int32_t SystemNative_ConvertErrorPalToPlatform(int32_t error)
  348. {
  349. switch (error)
  350. {
  351. case Error_SUCCESS:
  352. return 0;
  353. case Error_E2BIG:
  354. return E2BIG;
  355. case Error_EACCES:
  356. return EACCES;
  357. case Error_EADDRINUSE:
  358. return EADDRINUSE;
  359. case Error_EADDRNOTAVAIL:
  360. return EADDRNOTAVAIL;
  361. case Error_EAFNOSUPPORT:
  362. return EAFNOSUPPORT;
  363. case Error_EAGAIN:
  364. return EAGAIN;
  365. case Error_EALREADY:
  366. return EALREADY;
  367. case Error_EBADF:
  368. return EBADF;
  369. case Error_EBADMSG:
  370. return EBADMSG;
  371. case Error_EBUSY:
  372. return EBUSY;
  373. case Error_ECANCELED:
  374. return ECANCELED;
  375. case Error_ECHILD:
  376. return ECHILD;
  377. case Error_ECONNABORTED:
  378. return ECONNABORTED;
  379. case Error_ECONNREFUSED:
  380. return ECONNREFUSED;
  381. case Error_ECONNRESET:
  382. return ECONNRESET;
  383. case Error_EDEADLK:
  384. return EDEADLK;
  385. case Error_EDESTADDRREQ:
  386. return EDESTADDRREQ;
  387. case Error_EDOM:
  388. return EDOM;
  389. case Error_EDQUOT:
  390. return EDQUOT;
  391. case Error_EEXIST:
  392. return EEXIST;
  393. case Error_EFAULT:
  394. return EFAULT;
  395. case Error_EFBIG:
  396. return EFBIG;
  397. case Error_EHOSTUNREACH:
  398. return EHOSTUNREACH;
  399. case Error_EIDRM:
  400. return EIDRM;
  401. case Error_EILSEQ:
  402. return EILSEQ;
  403. case Error_EINPROGRESS:
  404. return EINPROGRESS;
  405. case Error_EINTR:
  406. return EINTR;
  407. case Error_EINVAL:
  408. return EINVAL;
  409. case Error_EIO:
  410. return EIO;
  411. case Error_EISCONN:
  412. return EISCONN;
  413. case Error_EISDIR:
  414. return EISDIR;
  415. case Error_ELOOP:
  416. return ELOOP;
  417. case Error_EMFILE:
  418. return EMFILE;
  419. case Error_EMLINK:
  420. return EMLINK;
  421. case Error_EMSGSIZE:
  422. return EMSGSIZE;
  423. case Error_EMULTIHOP:
  424. return EMULTIHOP;
  425. case Error_ENAMETOOLONG:
  426. return ENAMETOOLONG;
  427. case Error_ENETDOWN:
  428. return ENETDOWN;
  429. case Error_ENETRESET:
  430. return ENETRESET;
  431. case Error_ENETUNREACH:
  432. return ENETUNREACH;
  433. case Error_ENFILE:
  434. return ENFILE;
  435. case Error_ENOBUFS:
  436. return ENOBUFS;
  437. case Error_ENODEV:
  438. return ENODEV;
  439. case Error_ENOENT:
  440. return ENOENT;
  441. case Error_ENOEXEC:
  442. return ENOEXEC;
  443. case Error_ENOLCK:
  444. return ENOLCK;
  445. case Error_ENOLINK:
  446. return ENOLINK;
  447. case Error_ENOMEM:
  448. return ENOMEM;
  449. case Error_ENOMSG:
  450. return ENOMSG;
  451. case Error_ENOPROTOOPT:
  452. return ENOPROTOOPT;
  453. case Error_ENOSPC:
  454. return ENOSPC;
  455. case Error_ENOSYS:
  456. return ENOSYS;
  457. case Error_ENOTCONN:
  458. return ENOTCONN;
  459. case Error_ENOTDIR:
  460. return ENOTDIR;
  461. case Error_ENOTEMPTY:
  462. return ENOTEMPTY;
  463. #ifdef ENOTRECOVERABLE // not available in NetBSD
  464. case Error_ENOTRECOVERABLE:
  465. return ENOTRECOVERABLE;
  466. #endif
  467. case Error_ENOTSOCK:
  468. return ENOTSOCK;
  469. case Error_ENOTSUP:
  470. return ENOTSUP;
  471. case Error_ENOTTY:
  472. return ENOTTY;
  473. case Error_ENXIO:
  474. return ENXIO;
  475. case Error_EOVERFLOW:
  476. return EOVERFLOW;
  477. #ifdef EOWNERDEAD // not available in NetBSD
  478. case Error_EOWNERDEAD:
  479. return EOWNERDEAD;
  480. #endif
  481. case Error_EPERM:
  482. return EPERM;
  483. case Error_EPIPE:
  484. return EPIPE;
  485. case Error_EPROTO:
  486. return EPROTO;
  487. case Error_EPROTONOSUPPORT:
  488. return EPROTONOSUPPORT;
  489. case Error_EPROTOTYPE:
  490. return EPROTOTYPE;
  491. case Error_ERANGE:
  492. return ERANGE;
  493. case Error_EROFS:
  494. return EROFS;
  495. case Error_ESPIPE:
  496. return ESPIPE;
  497. case Error_ESRCH:
  498. return ESRCH;
  499. case Error_ESTALE:
  500. return ESTALE;
  501. case Error_ETIMEDOUT:
  502. return ETIMEDOUT;
  503. case Error_ETXTBSY:
  504. return ETXTBSY;
  505. case Error_EXDEV:
  506. return EXDEV;
  507. case Error_EPFNOSUPPORT:
  508. return EPFNOSUPPORT;
  509. #ifdef ESOCKTNOSUPPORT
  510. case Error_ESOCKTNOSUPPORT:
  511. return ESOCKTNOSUPPORT;
  512. #endif
  513. case Error_ESHUTDOWN:
  514. return ESHUTDOWN;
  515. case Error_EHOSTDOWN:
  516. return EHOSTDOWN;
  517. case Error_ENODATA:
  518. return ENODATA;
  519. case Error_ENONSTANDARD:
  520. break; // fall through to assert
  521. }
  522. // We should not use this function to round-trip platform -> pal
  523. // -> platform. It's here only to synthesize a platform number
  524. // from the fixed set above. Note that the assert is outside the
  525. // switch rather than in a default case block because not
  526. // having a default will trigger a warning (as error) if there's
  527. // an enum value we haven't handled. Should that trigger, make
  528. // note that there is probably a corresponding missing case in the
  529. // other direction above, but the compiler can't warn in that case
  530. // because the platform values are not part of an enum.
  531. IL2CPP_ASSERT(0 && "Unknown error code");
  532. return -1;
  533. }
  534. #endif