__xpg_strerror_r.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * Copyright (C) 2002 Manuel Novoa III
  3. * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
  4. *
  5. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  6. */
  7. #include <features.h>
  8. #include <errno.h>
  9. #include <string.h>
  10. #include "_syserrmsg.h"
  11. #ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
  12. extern const char _string_syserrmsgs[] attribute_hidden;
  13. #if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
  14. static const unsigned char estridx[] = {
  15. 0, /* success is always 0 */
  16. EPERM,
  17. ENOENT,
  18. ESRCH,
  19. EINTR,
  20. EIO,
  21. ENXIO,
  22. E2BIG,
  23. ENOEXEC,
  24. EBADF,
  25. ECHILD,
  26. EAGAIN,
  27. ENOMEM,
  28. EACCES,
  29. EFAULT,
  30. ENOTBLK,
  31. EBUSY,
  32. EEXIST,
  33. EXDEV,
  34. ENODEV,
  35. ENOTDIR,
  36. EISDIR,
  37. EINVAL,
  38. ENFILE,
  39. EMFILE,
  40. ENOTTY,
  41. ETXTBSY,
  42. EFBIG,
  43. ENOSPC,
  44. ESPIPE,
  45. EROFS,
  46. EMLINK,
  47. EPIPE,
  48. EDOM,
  49. ERANGE,
  50. EDEADLK,
  51. ENAMETOOLONG,
  52. ENOLCK,
  53. ENOSYS,
  54. ENOTEMPTY,
  55. ELOOP,
  56. 0,
  57. ENOMSG,
  58. EIDRM,
  59. ECHRNG,
  60. EL2NSYNC,
  61. EL3HLT,
  62. EL3RST,
  63. ELNRNG,
  64. EUNATCH,
  65. ENOCSI,
  66. EL2HLT,
  67. EBADE,
  68. EBADR,
  69. EXFULL,
  70. ENOANO,
  71. EBADRQC,
  72. EBADSLT,
  73. 0,
  74. EBFONT,
  75. ENOSTR,
  76. ENODATA,
  77. ETIME,
  78. ENOSR,
  79. ENONET,
  80. ENOPKG,
  81. EREMOTE,
  82. ENOLINK,
  83. EADV,
  84. ESRMNT,
  85. ECOMM,
  86. EPROTO,
  87. EMULTIHOP,
  88. EDOTDOT,
  89. EBADMSG,
  90. EOVERFLOW,
  91. ENOTUNIQ,
  92. EBADFD,
  93. EREMCHG,
  94. ELIBACC,
  95. ELIBBAD,
  96. ELIBSCN,
  97. ELIBMAX,
  98. ELIBEXEC,
  99. EILSEQ,
  100. ERESTART,
  101. ESTRPIPE,
  102. EUSERS,
  103. ENOTSOCK,
  104. EDESTADDRREQ,
  105. EMSGSIZE,
  106. EPROTOTYPE,
  107. ENOPROTOOPT,
  108. EPROTONOSUPPORT,
  109. ESOCKTNOSUPPORT,
  110. EOPNOTSUPP,
  111. EPFNOSUPPORT,
  112. EAFNOSUPPORT,
  113. EADDRINUSE,
  114. EADDRNOTAVAIL,
  115. ENETDOWN,
  116. ENETUNREACH,
  117. ENETRESET,
  118. ECONNABORTED,
  119. ECONNRESET,
  120. ENOBUFS,
  121. EISCONN,
  122. ENOTCONN,
  123. ESHUTDOWN,
  124. ETOOMANYREFS,
  125. ETIMEDOUT,
  126. ECONNREFUSED,
  127. EHOSTDOWN,
  128. EHOSTUNREACH,
  129. EALREADY,
  130. EINPROGRESS,
  131. ESTALE,
  132. EUCLEAN,
  133. ENOTNAM,
  134. ENAVAIL,
  135. EISNAM,
  136. EREMOTEIO,
  137. #if EDQUOT > 200 /* mips has an outrageous value for this... */
  138. 0,
  139. #else
  140. EDQUOT,
  141. #endif
  142. ENOMEDIUM,
  143. EMEDIUMTYPE,
  144. #if EDEADLOCK != EDEADLK
  145. EDEADLOCK,
  146. #endif
  147. };
  148. #endif
  149. int __xpg_strerror_r(int errnum, char *strerrbuf, size_t buflen)
  150. {
  151. register char *s;
  152. int i, retval;
  153. char buf[_STRERROR_BUFSIZE];
  154. static const char unknown[] = {
  155. 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' '
  156. };
  157. retval = EINVAL;
  158. #ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
  159. #if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
  160. /* Need to translate errno to string index. */
  161. for (i = 0 ; i < sizeof(estridx)/sizeof(estridx[0]) ; i++) {
  162. if (estridx[i] == errnum) {
  163. goto GOT_ESTRIDX;
  164. }
  165. }
  166. i = INT_MAX; /* Failed, but may need to check mips special case. */
  167. #if EDQUOT > 200 /* Deal with large EDQUOT value on mips */
  168. if (errnum == EDQUOT)
  169. i = 122;
  170. #endif
  171. GOT_ESTRIDX:
  172. #else
  173. /* No errno to string index translation needed. */
  174. i = errnum;
  175. #endif
  176. if (((unsigned int) i) < _SYS_NERR) {
  177. /* Trade time for space. This function should rarely be called
  178. * so rather than keeping an array of pointers for the different
  179. * messages, just run through the buffer until we find the
  180. * correct string. */
  181. for (s = (char *) _string_syserrmsgs ; i ; ++s) {
  182. if (!*s) {
  183. --i;
  184. }
  185. }
  186. if (*s) { /* Make sure we have an actual message. */
  187. retval = 0;
  188. goto GOT_MESG;
  189. }
  190. }
  191. #endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
  192. s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
  193. memcpy(s, unknown, sizeof(unknown));
  194. GOT_MESG:
  195. if (!strerrbuf) { /* SUSv3 */
  196. buflen = 0;
  197. }
  198. i = strlen(s) + 1;
  199. if (i > buflen) {
  200. i = buflen;
  201. retval = ERANGE;
  202. }
  203. if (i) {
  204. memcpy(strerrbuf, s, i);
  205. strerrbuf[i-1] = 0; /* In case buf was too small. */
  206. }
  207. if (retval) {
  208. __set_errno(retval);
  209. }
  210. return retval;
  211. }
  212. #else /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
  213. int __xpg_strerror_r(int errnum, char *strerrbuf, size_t buflen)
  214. {
  215. register char *s;
  216. int i, retval;
  217. char buf[_STRERROR_BUFSIZE];
  218. static const char unknown[] = {
  219. 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' '
  220. };
  221. s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
  222. memcpy(s, unknown, sizeof(unknown));
  223. if (!strerrbuf) { /* SUSv3 */
  224. buflen = 0;
  225. }
  226. retval = EINVAL;
  227. i = buf + sizeof(buf) - s;
  228. if (i > buflen) {
  229. i = buflen;
  230. retval = ERANGE;
  231. }
  232. if (i) {
  233. memcpy(strerrbuf, s, i);
  234. strerrbuf[i-1] = 0; /* In case buf was too small. */
  235. }
  236. __set_errno(retval);
  237. return retval;
  238. }
  239. #endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
  240. libc_hidden_def(__xpg_strerror_r)
  241. strong_alias_untyped(__xpg_strerror_r, strerror_r)