_errno.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include "lib.h"
  2. #include "sys9.h"
  3. #include <string.h>
  4. #include <errno.h>
  5. /* make this global, so programs can look at it if errno is unilluminating */
  6. /* see also: ../stdio/strerror.c, with errno-> string mapping */
  7. char _plan9err[ERRMAX];
  8. static struct errmap {
  9. int errno;
  10. char *ename;
  11. } map[] = {
  12. /* from /sys/src/9/port/errstr.h */
  13. {EINVAL, "inconsistent mount"},
  14. {EINVAL, "not mounted"},
  15. {EINVAL, "not in union"},
  16. {EIO, "mount rpc error"},
  17. {EIO, "mounted device shut down"},
  18. {EPERM, "mounted directory forbids creation"},
  19. {ENOENT, "does not exist"},
  20. {ENXIO, "unknown device in # filename"},
  21. {ENOTDIR, "not a directory"},
  22. {EISDIR, "file is a directory"},
  23. {EINVAL, "bad character in file name"},
  24. {EINVAL, "file name syntax"},
  25. {EPERM, "permission denied"},
  26. {EPERM, "inappropriate use of fd"},
  27. {EINVAL, "bad arg in system call"},
  28. {EBUSY, "device or object already in use"},
  29. {EIO, "i/o error"},
  30. {EIO, "read or write too large"},
  31. {EIO, "read or write too small"},
  32. {EADDRINUSE, "network port not available"},
  33. {ESHUTDOWN, "write to hungup stream"},
  34. {ESHUTDOWN, "i/o on hungup channel"},
  35. {EINVAL, "bad process or channel control request"},
  36. {EBUSY, "no free devices"},
  37. {ESRCH, "process exited"},
  38. {ECHILD, "no living children"},
  39. {EIO, "i/o error in demand load"},
  40. {ENOMEM, "virtual memory allocation failed"},
  41. {EBADF, "fd out of range or not open"},
  42. {EMFILE, "no free file descriptors"},
  43. {ESPIPE, "seek on a stream"},
  44. {ENOEXEC, "exec header invalid"},
  45. {ETIMEDOUT, "connection timed out"},
  46. {ECONNREFUSED, "connection refused"},
  47. {ECONNREFUSED, "connection in use"},
  48. {EINTR, "interrupted"},
  49. {ENOMEM, "kernel allocate failed"},
  50. {EINVAL, "segments overlap"},
  51. {EIO, "i/o count too small"},
  52. {EGREG, "ken has left the building"},
  53. {EINVAL, "bad attach specifier"},
  54. /* from exhausted() calls in kernel */
  55. {ENFILE, "no free file descriptors"},
  56. {EBUSY, "no free mount devices"},
  57. {EBUSY, "no free mount rpc buffer"},
  58. {EBUSY, "no free segments"},
  59. {ENOMEM, "no free memory"},
  60. {ENOBUFS, "no free Blocks"},
  61. {EBUSY, "no free routes"},
  62. /* from ken */
  63. {EINVAL, "attach -- bad specifier"},
  64. {EBADF, "unknown fid"},
  65. {EINVAL, "bad character in directory name"},
  66. {EBADF, "read/write -- on non open fid"},
  67. {EIO, "read/write -- count too big"},
  68. {EIO, "phase error -- directory entry not allocated"},
  69. {EIO, "phase error -- qid does not match"},
  70. {EACCES, "access permission denied"},
  71. {ENOENT, "directory entry not found"},
  72. {EINVAL, "open/create -- unknown mode"},
  73. {ENOTDIR, "walk -- in a non-directory"},
  74. {ENOTDIR, "create -- in a non-directory"},
  75. {EIO, "phase error -- cannot happen"},
  76. {EEXIST, "create -- file exists"},
  77. {EINVAL, "create -- . and .. illegal names"},
  78. {ENOTEMPTY, "directory not empty"},
  79. {EINVAL, "attach -- privileged user"},
  80. {EPERM, "wstat -- not owner"},
  81. {EPERM, "wstat -- not in group"},
  82. {EINVAL, "create/wstat -- bad character in file name"},
  83. {EBUSY, "walk -- too many (system wide)"},
  84. {EROFS, "file system read only"},
  85. {ENOSPC, "file system full"},
  86. {EINVAL, "read/write -- offset negative"},
  87. {EBUSY, "open/create -- file is locked"},
  88. {EBUSY, "close/read/write -- lock is broken"},
  89. /* from sockets */
  90. {ENOTSOCK, "not a socket"},
  91. {EPROTONOSUPPORT, "protocol not supported"},
  92. {ECONNREFUSED, "connection refused"},
  93. {EAFNOSUPPORT, "address family not supported"},
  94. {ENOBUFS, "insufficient buffer space"},
  95. {EOPNOTSUPP, "operation not supported"},
  96. {EADDRINUSE, "address in use"},
  97. {EGREG, "unnamed error message"},
  98. };
  99. #define NERRMAP (sizeof(map)/sizeof(struct errmap))
  100. /* convert last system call error to an errno */
  101. void
  102. _syserrno(void)
  103. {
  104. int i;
  105. if(_ERRSTR(_plan9err, sizeof _plan9err) < 0)
  106. errno = EINVAL;
  107. else{
  108. for(i = 0; i < NERRMAP; i++)
  109. if(strstr(_plan9err, map[i].ename) != 0)
  110. break;
  111. _ERRSTR(_plan9err, sizeof _plan9err);
  112. errno = (i < NERRMAP)? map[i].errno : EINVAL;
  113. }
  114. }