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