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