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