strerror.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814
  1. /* Extended support for using errno values.
  2. Written by Fred Fish. fnf@cygnus.com
  3. This file is in the public domain. --Per Bothner. */
  4. #include "config.h"
  5. #ifdef HAVE_SYS_ERRLIST
  6. /* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least)
  7. might declare sys_errlist in a way that the compiler might consider
  8. incompatible with our later declaration, perhaps by using const
  9. attributes. So we hide the declaration in errno.h (if any) using a
  10. macro. */
  11. #define sys_nerr sys_nerr__
  12. #define sys_errlist sys_errlist__
  13. #endif
  14. #include "ansidecl.h"
  15. #include "libiberty.h"
  16. #include <stdio.h>
  17. #include <errno.h>
  18. #ifdef HAVE_SYS_ERRLIST
  19. #undef sys_nerr
  20. #undef sys_errlist
  21. #endif
  22. /* Routines imported from standard C runtime libraries. */
  23. #ifdef HAVE_STDLIB_H
  24. #include <stdlib.h>
  25. #else
  26. extern PTR malloc ();
  27. #endif
  28. #ifdef HAVE_STRING_H
  29. #include <string.h>
  30. #else
  31. extern PTR memset ();
  32. #endif
  33. #ifndef MAX
  34. # define MAX(a,b) ((a) > (b) ? (a) : (b))
  35. #endif
  36. static void init_error_tables (void);
  37. /* Translation table for errno values. See intro(2) in most UNIX systems
  38. Programmers Reference Manuals.
  39. Note that this table is generally only accessed when it is used at runtime
  40. to initialize errno name and message tables that are indexed by errno
  41. value.
  42. Not all of these errnos will exist on all systems. This table is the only
  43. thing that should have to be updated as new error numbers are introduced.
  44. It's sort of ugly, but at least its portable. */
  45. struct error_info
  46. {
  47. const int value; /* The numeric value from <errno.h> */
  48. const char *const name; /* The equivalent symbolic value */
  49. #ifndef HAVE_SYS_ERRLIST
  50. const char *const msg; /* Short message about this value */
  51. #endif
  52. };
  53. #ifndef HAVE_SYS_ERRLIST
  54. # define ENTRY(value, name, msg) {value, name, msg}
  55. #else
  56. # define ENTRY(value, name, msg) {value, name}
  57. #endif
  58. static const struct error_info error_table[] =
  59. {
  60. #if defined (EPERM)
  61. ENTRY(EPERM, "EPERM", "Not owner"),
  62. #endif
  63. #if defined (ENOENT)
  64. ENTRY(ENOENT, "ENOENT", "No such file or directory"),
  65. #endif
  66. #if defined (ESRCH)
  67. ENTRY(ESRCH, "ESRCH", "No such process"),
  68. #endif
  69. #if defined (EINTR)
  70. ENTRY(EINTR, "EINTR", "Interrupted system call"),
  71. #endif
  72. #if defined (EIO)
  73. ENTRY(EIO, "EIO", "I/O error"),
  74. #endif
  75. #if defined (ENXIO)
  76. ENTRY(ENXIO, "ENXIO", "No such device or address"),
  77. #endif
  78. #if defined (E2BIG)
  79. ENTRY(E2BIG, "E2BIG", "Arg list too long"),
  80. #endif
  81. #if defined (ENOEXEC)
  82. ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"),
  83. #endif
  84. #if defined (EBADF)
  85. ENTRY(EBADF, "EBADF", "Bad file number"),
  86. #endif
  87. #if defined (ECHILD)
  88. ENTRY(ECHILD, "ECHILD", "No child processes"),
  89. #endif
  90. #if defined (EWOULDBLOCK) /* Put before EAGAIN, sometimes aliased */
  91. ENTRY(EWOULDBLOCK, "EWOULDBLOCK", "Operation would block"),
  92. #endif
  93. #if defined (EAGAIN)
  94. ENTRY(EAGAIN, "EAGAIN", "No more processes"),
  95. #endif
  96. #if defined (ENOMEM)
  97. ENTRY(ENOMEM, "ENOMEM", "Not enough space"),
  98. #endif
  99. #if defined (EACCES)
  100. ENTRY(EACCES, "EACCES", "Permission denied"),
  101. #endif
  102. #if defined (EFAULT)
  103. ENTRY(EFAULT, "EFAULT", "Bad address"),
  104. #endif
  105. #if defined (ENOTBLK)
  106. ENTRY(ENOTBLK, "ENOTBLK", "Block device required"),
  107. #endif
  108. #if defined (EBUSY)
  109. ENTRY(EBUSY, "EBUSY", "Device busy"),
  110. #endif
  111. #if defined (EEXIST)
  112. ENTRY(EEXIST, "EEXIST", "File exists"),
  113. #endif
  114. #if defined (EXDEV)
  115. ENTRY(EXDEV, "EXDEV", "Cross-device link"),
  116. #endif
  117. #if defined (ENODEV)
  118. ENTRY(ENODEV, "ENODEV", "No such device"),
  119. #endif
  120. #if defined (ENOTDIR)
  121. ENTRY(ENOTDIR, "ENOTDIR", "Not a directory"),
  122. #endif
  123. #if defined (EISDIR)
  124. ENTRY(EISDIR, "EISDIR", "Is a directory"),
  125. #endif
  126. #if defined (EINVAL)
  127. ENTRY(EINVAL, "EINVAL", "Invalid argument"),
  128. #endif
  129. #if defined (ENFILE)
  130. ENTRY(ENFILE, "ENFILE", "File table overflow"),
  131. #endif
  132. #if defined (EMFILE)
  133. ENTRY(EMFILE, "EMFILE", "Too many open files"),
  134. #endif
  135. #if defined (ENOTTY)
  136. ENTRY(ENOTTY, "ENOTTY", "Not a typewriter"),
  137. #endif
  138. #if defined (ETXTBSY)
  139. ENTRY(ETXTBSY, "ETXTBSY", "Text file busy"),
  140. #endif
  141. #if defined (EFBIG)
  142. ENTRY(EFBIG, "EFBIG", "File too large"),
  143. #endif
  144. #if defined (ENOSPC)
  145. ENTRY(ENOSPC, "ENOSPC", "No space left on device"),
  146. #endif
  147. #if defined (ESPIPE)
  148. ENTRY(ESPIPE, "ESPIPE", "Illegal seek"),
  149. #endif
  150. #if defined (EROFS)
  151. ENTRY(EROFS, "EROFS", "Read-only file system"),
  152. #endif
  153. #if defined (EMLINK)
  154. ENTRY(EMLINK, "EMLINK", "Too many links"),
  155. #endif
  156. #if defined (EPIPE)
  157. ENTRY(EPIPE, "EPIPE", "Broken pipe"),
  158. #endif
  159. #if defined (EDOM)
  160. ENTRY(EDOM, "EDOM", "Math argument out of domain of func"),
  161. #endif
  162. #if defined (ERANGE)
  163. ENTRY(ERANGE, "ERANGE", "Math result not representable"),
  164. #endif
  165. #if defined (ENOMSG)
  166. ENTRY(ENOMSG, "ENOMSG", "No message of desired type"),
  167. #endif
  168. #if defined (EIDRM)
  169. ENTRY(EIDRM, "EIDRM", "Identifier removed"),
  170. #endif
  171. #if defined (ECHRNG)
  172. ENTRY(ECHRNG, "ECHRNG", "Channel number out of range"),
  173. #endif
  174. #if defined (EL2NSYNC)
  175. ENTRY(EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized"),
  176. #endif
  177. #if defined (EL3HLT)
  178. ENTRY(EL3HLT, "EL3HLT", "Level 3 halted"),
  179. #endif
  180. #if defined (EL3RST)
  181. ENTRY(EL3RST, "EL3RST", "Level 3 reset"),
  182. #endif
  183. #if defined (ELNRNG)
  184. ENTRY(ELNRNG, "ELNRNG", "Link number out of range"),
  185. #endif
  186. #if defined (EUNATCH)
  187. ENTRY(EUNATCH, "EUNATCH", "Protocol driver not attached"),
  188. #endif
  189. #if defined (ENOCSI)
  190. ENTRY(ENOCSI, "ENOCSI", "No CSI structure available"),
  191. #endif
  192. #if defined (EL2HLT)
  193. ENTRY(EL2HLT, "EL2HLT", "Level 2 halted"),
  194. #endif
  195. #if defined (EDEADLK)
  196. ENTRY(EDEADLK, "EDEADLK", "Deadlock condition"),
  197. #endif
  198. #if defined (ENOLCK)
  199. ENTRY(ENOLCK, "ENOLCK", "No record locks available"),
  200. #endif
  201. #if defined (EBADE)
  202. ENTRY(EBADE, "EBADE", "Invalid exchange"),
  203. #endif
  204. #if defined (EBADR)
  205. ENTRY(EBADR, "EBADR", "Invalid request descriptor"),
  206. #endif
  207. #if defined (EXFULL)
  208. ENTRY(EXFULL, "EXFULL", "Exchange full"),
  209. #endif
  210. #if defined (ENOANO)
  211. ENTRY(ENOANO, "ENOANO", "No anode"),
  212. #endif
  213. #if defined (EBADRQC)
  214. ENTRY(EBADRQC, "EBADRQC", "Invalid request code"),
  215. #endif
  216. #if defined (EBADSLT)
  217. ENTRY(EBADSLT, "EBADSLT", "Invalid slot"),
  218. #endif
  219. #if defined (EDEADLOCK)
  220. ENTRY(EDEADLOCK, "EDEADLOCK", "File locking deadlock error"),
  221. #endif
  222. #if defined (EBFONT)
  223. ENTRY(EBFONT, "EBFONT", "Bad font file format"),
  224. #endif
  225. #if defined (ENOSTR)
  226. ENTRY(ENOSTR, "ENOSTR", "Device not a stream"),
  227. #endif
  228. #if defined (ENODATA)
  229. ENTRY(ENODATA, "ENODATA", "No data available"),
  230. #endif
  231. #if defined (ETIME)
  232. ENTRY(ETIME, "ETIME", "Timer expired"),
  233. #endif
  234. #if defined (ENOSR)
  235. ENTRY(ENOSR, "ENOSR", "Out of streams resources"),
  236. #endif
  237. #if defined (ENONET)
  238. ENTRY(ENONET, "ENONET", "Machine is not on the network"),
  239. #endif
  240. #if defined (ENOPKG)
  241. ENTRY(ENOPKG, "ENOPKG", "Package not installed"),
  242. #endif
  243. #if defined (EREMOTE)
  244. ENTRY(EREMOTE, "EREMOTE", "Object is remote"),
  245. #endif
  246. #if defined (ENOLINK)
  247. ENTRY(ENOLINK, "ENOLINK", "Link has been severed"),
  248. #endif
  249. #if defined (EADV)
  250. ENTRY(EADV, "EADV", "Advertise error"),
  251. #endif
  252. #if defined (ESRMNT)
  253. ENTRY(ESRMNT, "ESRMNT", "Srmount error"),
  254. #endif
  255. #if defined (ECOMM)
  256. ENTRY(ECOMM, "ECOMM", "Communication error on send"),
  257. #endif
  258. #if defined (EPROTO)
  259. ENTRY(EPROTO, "EPROTO", "Protocol error"),
  260. #endif
  261. #if defined (EMULTIHOP)
  262. ENTRY(EMULTIHOP, "EMULTIHOP", "Multihop attempted"),
  263. #endif
  264. #if defined (EDOTDOT)
  265. ENTRY(EDOTDOT, "EDOTDOT", "RFS specific error"),
  266. #endif
  267. #if defined (EBADMSG)
  268. ENTRY(EBADMSG, "EBADMSG", "Not a data message"),
  269. #endif
  270. #if defined (ENAMETOOLONG)
  271. ENTRY(ENAMETOOLONG, "ENAMETOOLONG", "File name too long"),
  272. #endif
  273. #if defined (EOVERFLOW)
  274. ENTRY(EOVERFLOW, "EOVERFLOW", "Value too large for defined data type"),
  275. #endif
  276. #if defined (ENOTUNIQ)
  277. ENTRY(ENOTUNIQ, "ENOTUNIQ", "Name not unique on network"),
  278. #endif
  279. #if defined (EBADFD)
  280. ENTRY(EBADFD, "EBADFD", "File descriptor in bad state"),
  281. #endif
  282. #if defined (EREMCHG)
  283. ENTRY(EREMCHG, "EREMCHG", "Remote address changed"),
  284. #endif
  285. #if defined (ELIBACC)
  286. ENTRY(ELIBACC, "ELIBACC", "Cannot access a needed shared library"),
  287. #endif
  288. #if defined (ELIBBAD)
  289. ENTRY(ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library"),
  290. #endif
  291. #if defined (ELIBSCN)
  292. ENTRY(ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted"),
  293. #endif
  294. #if defined (ELIBMAX)
  295. ENTRY(ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries"),
  296. #endif
  297. #if defined (ELIBEXEC)
  298. ENTRY(ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly"),
  299. #endif
  300. #if defined (EILSEQ)
  301. ENTRY(EILSEQ, "EILSEQ", "Illegal byte sequence"),
  302. #endif
  303. #if defined (ENOSYS)
  304. ENTRY(ENOSYS, "ENOSYS", "Operation not applicable"),
  305. #endif
  306. #if defined (ELOOP)
  307. ENTRY(ELOOP, "ELOOP", "Too many symbolic links encountered"),
  308. #endif
  309. #if defined (ERESTART)
  310. ENTRY(ERESTART, "ERESTART", "Interrupted system call should be restarted"),
  311. #endif
  312. #if defined (ESTRPIPE)
  313. ENTRY(ESTRPIPE, "ESTRPIPE", "Streams pipe error"),
  314. #endif
  315. #if defined (ENOTEMPTY)
  316. ENTRY(ENOTEMPTY, "ENOTEMPTY", "Directory not empty"),
  317. #endif
  318. #if defined (EUSERS)
  319. ENTRY(EUSERS, "EUSERS", "Too many users"),
  320. #endif
  321. #if defined (ENOTSOCK)
  322. ENTRY(ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket"),
  323. #endif
  324. #if defined (EDESTADDRREQ)
  325. ENTRY(EDESTADDRREQ, "EDESTADDRREQ", "Destination address required"),
  326. #endif
  327. #if defined (EMSGSIZE)
  328. ENTRY(EMSGSIZE, "EMSGSIZE", "Message too long"),
  329. #endif
  330. #if defined (EPROTOTYPE)
  331. ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"),
  332. #endif
  333. #if defined (ENOPROTOOPT)
  334. ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available"),
  335. #endif
  336. #if defined (EPROTONOSUPPORT)
  337. ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"),
  338. #endif
  339. #if defined (ESOCKTNOSUPPORT)
  340. ENTRY(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported"),
  341. #endif
  342. #if defined (EOPNOTSUPP)
  343. ENTRY(EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint"),
  344. #endif
  345. #if defined (EPFNOSUPPORT)
  346. ENTRY(EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported"),
  347. #endif
  348. #if defined (EAFNOSUPPORT)
  349. ENTRY(EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol"),
  350. #endif
  351. #if defined (EADDRINUSE)
  352. ENTRY(EADDRINUSE, "EADDRINUSE", "Address already in use"),
  353. #endif
  354. #if defined (EADDRNOTAVAIL)
  355. ENTRY(EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address"),
  356. #endif
  357. #if defined (ENETDOWN)
  358. ENTRY(ENETDOWN, "ENETDOWN", "Network is down"),
  359. #endif
  360. #if defined (ENETUNREACH)
  361. ENTRY(ENETUNREACH, "ENETUNREACH", "Network is unreachable"),
  362. #endif
  363. #if defined (ENETRESET)
  364. ENTRY(ENETRESET, "ENETRESET", "Network dropped connection because of reset"),
  365. #endif
  366. #if defined (ECONNABORTED)
  367. ENTRY(ECONNABORTED, "ECONNABORTED", "Software caused connection abort"),
  368. #endif
  369. #if defined (ECONNRESET)
  370. ENTRY(ECONNRESET, "ECONNRESET", "Connection reset by peer"),
  371. #endif
  372. #if defined (ENOBUFS)
  373. ENTRY(ENOBUFS, "ENOBUFS", "No buffer space available"),
  374. #endif
  375. #if defined (EISCONN)
  376. ENTRY(EISCONN, "EISCONN", "Transport endpoint is already connected"),
  377. #endif
  378. #if defined (ENOTCONN)
  379. ENTRY(ENOTCONN, "ENOTCONN", "Transport endpoint is not connected"),
  380. #endif
  381. #if defined (ESHUTDOWN)
  382. ENTRY(ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"),
  383. #endif
  384. #if defined (ETOOMANYREFS)
  385. ENTRY(ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice"),
  386. #endif
  387. #if defined (ETIMEDOUT)
  388. ENTRY(ETIMEDOUT, "ETIMEDOUT", "Connection timed out"),
  389. #endif
  390. #if defined (ECONNREFUSED)
  391. ENTRY(ECONNREFUSED, "ECONNREFUSED", "Connection refused"),
  392. #endif
  393. #if defined (EHOSTDOWN)
  394. ENTRY(EHOSTDOWN, "EHOSTDOWN", "Host is down"),
  395. #endif
  396. #if defined (EHOSTUNREACH)
  397. ENTRY(EHOSTUNREACH, "EHOSTUNREACH", "No route to host"),
  398. #endif
  399. #if defined (EALREADY)
  400. ENTRY(EALREADY, "EALREADY", "Operation already in progress"),
  401. #endif
  402. #if defined (EINPROGRESS)
  403. ENTRY(EINPROGRESS, "EINPROGRESS", "Operation now in progress"),
  404. #endif
  405. #if defined (ESTALE)
  406. ENTRY(ESTALE, "ESTALE", "Stale NFS file handle"),
  407. #endif
  408. #if defined (EUCLEAN)
  409. ENTRY(EUCLEAN, "EUCLEAN", "Structure needs cleaning"),
  410. #endif
  411. #if defined (ENOTNAM)
  412. ENTRY(ENOTNAM, "ENOTNAM", "Not a XENIX named type file"),
  413. #endif
  414. #if defined (ENAVAIL)
  415. ENTRY(ENAVAIL, "ENAVAIL", "No XENIX semaphores available"),
  416. #endif
  417. #if defined (EISNAM)
  418. ENTRY(EISNAM, "EISNAM", "Is a named type file"),
  419. #endif
  420. #if defined (EREMOTEIO)
  421. ENTRY(EREMOTEIO, "EREMOTEIO", "Remote I/O error"),
  422. #endif
  423. ENTRY(0, NULL, NULL)
  424. };
  425. #ifdef EVMSERR
  426. /* This is not in the table, because the numeric value of EVMSERR (32767)
  427. lies outside the range of sys_errlist[]. */
  428. static struct { int value; const char *name, *msg; }
  429. evmserr = { EVMSERR, "EVMSERR", "VMS-specific error" };
  430. #endif
  431. /* Translation table allocated and initialized at runtime. Indexed by the
  432. errno value to find the equivalent symbolic value. */
  433. static const char **error_names;
  434. static int num_error_names = 0;
  435. /* Translation table allocated and initialized at runtime, if it does not
  436. already exist in the host environment. Indexed by the errno value to find
  437. the descriptive string.
  438. We don't export it for use in other modules because even though it has the
  439. same name, it differs from other implementations in that it is dynamically
  440. initialized rather than statically initialized. */
  441. #ifndef HAVE_SYS_ERRLIST
  442. #define sys_nerr sys_nerr__
  443. #define sys_errlist sys_errlist__
  444. static int sys_nerr;
  445. static const char **sys_errlist;
  446. #else
  447. #ifndef sys_nerr
  448. extern int sys_nerr;
  449. #endif
  450. #ifndef sys_errlist
  451. extern char *sys_errlist[];
  452. #endif
  453. #endif
  454. /*
  455. NAME
  456. init_error_tables -- initialize the name and message tables
  457. SYNOPSIS
  458. static void init_error_tables ();
  459. DESCRIPTION
  460. Using the error_table, which is initialized at compile time, generate
  461. the error_names and the sys_errlist (if needed) tables, which are
  462. indexed at runtime by a specific errno value.
  463. BUGS
  464. The initialization of the tables may fail under low memory conditions,
  465. in which case we don't do anything particularly useful, but we don't
  466. bomb either. Who knows, it might succeed at a later point if we free
  467. some memory in the meantime. In any case, the other routines know
  468. how to deal with lack of a table after trying to initialize it. This
  469. may or may not be considered to be a bug, that we don't specifically
  470. warn about this particular failure mode.
  471. */
  472. static void
  473. init_error_tables (void)
  474. {
  475. const struct error_info *eip;
  476. int nbytes;
  477. /* If we haven't already scanned the error_table once to find the maximum
  478. errno value, then go find it now. */
  479. if (num_error_names == 0)
  480. {
  481. for (eip = error_table; eip -> name != NULL; eip++)
  482. {
  483. if (eip -> value >= num_error_names)
  484. {
  485. num_error_names = eip -> value + 1;
  486. }
  487. }
  488. }
  489. /* Now attempt to allocate the error_names table, zero it out, and then
  490. initialize it from the statically initialized error_table. */
  491. if (error_names == NULL)
  492. {
  493. nbytes = num_error_names * sizeof (char *);
  494. if ((error_names = (const char **) malloc (nbytes)) != NULL)
  495. {
  496. memset (error_names, 0, nbytes);
  497. for (eip = error_table; eip -> name != NULL; eip++)
  498. {
  499. error_names[eip -> value] = eip -> name;
  500. }
  501. }
  502. }
  503. #ifndef HAVE_SYS_ERRLIST
  504. /* Now attempt to allocate the sys_errlist table, zero it out, and then
  505. initialize it from the statically initialized error_table. */
  506. if (sys_errlist == NULL)
  507. {
  508. nbytes = num_error_names * sizeof (char *);
  509. if ((sys_errlist = (const char **) malloc (nbytes)) != NULL)
  510. {
  511. memset (sys_errlist, 0, nbytes);
  512. sys_nerr = num_error_names;
  513. for (eip = error_table; eip -> name != NULL; eip++)
  514. {
  515. sys_errlist[eip -> value] = eip -> msg;
  516. }
  517. }
  518. }
  519. #endif
  520. }
  521. /*
  522. @deftypefn Extension int errno_max (void)
  523. Returns the maximum @code{errno} value for which a corresponding
  524. symbolic name or message is available. Note that in the case where we
  525. use the @code{sys_errlist} supplied by the system, it is possible for
  526. there to be more symbolic names than messages, or vice versa. In
  527. fact, the manual page for @code{perror(3C)} explicitly warns that one
  528. should check the size of the table (@code{sys_nerr}) before indexing
  529. it, since new error codes may be added to the system before they are
  530. added to the table. Thus @code{sys_nerr} might be smaller than value
  531. implied by the largest @code{errno} value defined in @code{<errno.h>}.
  532. We return the maximum value that can be used to obtain a meaningful
  533. symbolic name or message.
  534. @end deftypefn
  535. */
  536. int
  537. errno_max (void)
  538. {
  539. int maxsize;
  540. if (error_names == NULL)
  541. {
  542. init_error_tables ();
  543. }
  544. maxsize = MAX (sys_nerr, num_error_names);
  545. return (maxsize - 1);
  546. }
  547. #ifndef HAVE_STRERROR
  548. /*
  549. @deftypefn Supplemental char* strerror (int @var{errnoval})
  550. Maps an @code{errno} number to an error message string, the contents
  551. of which are implementation defined. On systems which have the
  552. external variables @code{sys_nerr} and @code{sys_errlist}, these
  553. strings will be the same as the ones used by @code{perror}.
  554. If the supplied error number is within the valid range of indices for
  555. the @code{sys_errlist}, but no message is available for the particular
  556. error number, then returns the string @samp{Error @var{num}}, where
  557. @var{num} is the error number.
  558. If the supplied error number is not a valid index into
  559. @code{sys_errlist}, returns @code{NULL}.
  560. The returned string is only guaranteed to be valid only until the
  561. next call to @code{strerror}.
  562. @end deftypefn
  563. */
  564. char *
  565. strerror (int errnoval)
  566. {
  567. const char *msg;
  568. static char buf[32];
  569. #ifndef HAVE_SYS_ERRLIST
  570. if (error_names == NULL)
  571. {
  572. init_error_tables ();
  573. }
  574. #endif
  575. if ((errnoval < 0) || (errnoval >= sys_nerr))
  576. {
  577. #ifdef EVMSERR
  578. if (errnoval == evmserr.value)
  579. msg = evmserr.msg;
  580. else
  581. #endif
  582. /* Out of range, just return NULL */
  583. msg = NULL;
  584. }
  585. else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL))
  586. {
  587. /* In range, but no sys_errlist or no entry at this index. */
  588. sprintf (buf, "Error %d", errnoval);
  589. msg = buf;
  590. }
  591. else
  592. {
  593. /* In range, and a valid message. Just return the message. */
  594. msg = (char *) sys_errlist[errnoval];
  595. }
  596. return (msg);
  597. }
  598. #endif /* ! HAVE_STRERROR */
  599. /*
  600. @deftypefn Replacement {const char*} strerrno (int @var{errnum})
  601. Given an error number returned from a system call (typically returned
  602. in @code{errno}), returns a pointer to a string containing the
  603. symbolic name of that error number, as found in @code{<errno.h>}.
  604. If the supplied error number is within the valid range of indices for
  605. symbolic names, but no name is available for the particular error
  606. number, then returns the string @samp{Error @var{num}}, where @var{num}
  607. is the error number.
  608. If the supplied error number is not within the range of valid
  609. indices, then returns @code{NULL}.
  610. The contents of the location pointed to are only guaranteed to be
  611. valid until the next call to @code{strerrno}.
  612. @end deftypefn
  613. */
  614. const char *
  615. strerrno (int errnoval)
  616. {
  617. const char *name;
  618. static char buf[32];
  619. if (error_names == NULL)
  620. {
  621. init_error_tables ();
  622. }
  623. if ((errnoval < 0) || (errnoval >= num_error_names))
  624. {
  625. #ifdef EVMSERR
  626. if (errnoval == evmserr.value)
  627. name = evmserr.name;
  628. else
  629. #endif
  630. /* Out of range, just return NULL */
  631. name = NULL;
  632. }
  633. else if ((error_names == NULL) || (error_names[errnoval] == NULL))
  634. {
  635. /* In range, but no error_names or no entry at this index. */
  636. sprintf (buf, "Error %d", errnoval);
  637. name = (const char *) buf;
  638. }
  639. else
  640. {
  641. /* In range, and a valid name. Just return the name. */
  642. name = error_names[errnoval];
  643. }
  644. return (name);
  645. }
  646. /*
  647. @deftypefn Extension int strtoerrno (const char *@var{name})
  648. Given the symbolic name of a error number (e.g., @code{EACCES}), map it
  649. to an errno value. If no translation is found, returns 0.
  650. @end deftypefn
  651. */
  652. int
  653. strtoerrno (const char *name)
  654. {
  655. int errnoval = 0;
  656. if (name != NULL)
  657. {
  658. if (error_names == NULL)
  659. {
  660. init_error_tables ();
  661. }
  662. for (errnoval = 0; errnoval < num_error_names; errnoval++)
  663. {
  664. if ((error_names[errnoval] != NULL) &&
  665. (strcmp (name, error_names[errnoval]) == 0))
  666. {
  667. break;
  668. }
  669. }
  670. if (errnoval == num_error_names)
  671. {
  672. #ifdef EVMSERR
  673. if (strcmp (name, evmserr.name) == 0)
  674. errnoval = evmserr.value;
  675. else
  676. #endif
  677. errnoval = 0;
  678. }
  679. }
  680. return (errnoval);
  681. }
  682. /* A simple little main that does nothing but print all the errno translations
  683. if MAIN is defined and this file is compiled and linked. */
  684. #ifdef MAIN
  685. #include <stdio.h>
  686. int
  687. main (void)
  688. {
  689. int errn;
  690. int errnmax;
  691. const char *name;
  692. const char *msg;
  693. char *strerror ();
  694. errnmax = errno_max ();
  695. printf ("%d entries in names table.\n", num_error_names);
  696. printf ("%d entries in messages table.\n", sys_nerr);
  697. printf ("%d is max useful index.\n", errnmax);
  698. /* Keep printing values until we get to the end of *both* tables, not
  699. *either* table. Note that knowing the maximum useful index does *not*
  700. relieve us of the responsibility of testing the return pointer for
  701. NULL. */
  702. for (errn = 0; errn <= errnmax; errn++)
  703. {
  704. name = strerrno (errn);
  705. name = (name == NULL) ? "<NULL>" : name;
  706. msg = strerror (errn);
  707. msg = (msg == NULL) ? "<NULL>" : msg;
  708. printf ("%-4d%-18s%s\n", errn, name, msg);
  709. }
  710. return 0;
  711. }
  712. #endif