100bf4279Sespie /* xstrerror.c -- jacket routine for more robust strerror() usage.
200bf4279Sespie Fri Jun 16 18:30:00 1995 Pat Rankin <rankin@eql.caltech.edu>
300bf4279Sespie This code is in the public domain. */
400bf4279Sespie
59588ddcfSespie /*
69588ddcfSespie
79588ddcfSespie @deftypefn Replacement char* xstrerror (int @var{errnum})
89588ddcfSespie
99588ddcfSespie Behaves exactly like the standard @code{strerror} function, but
109588ddcfSespie will never return a @code{NULL} pointer.
119588ddcfSespie
129588ddcfSespie @end deftypefn
139588ddcfSespie
149588ddcfSespie */
159588ddcfSespie
1600bf4279Sespie #include <stdio.h>
1700bf4279Sespie
1800bf4279Sespie #include "config.h"
19150b7e42Smiod #include "libiberty.h"
2000bf4279Sespie
2100bf4279Sespie #ifdef VMS
2200bf4279Sespie # include <errno.h>
2300bf4279Sespie # if !defined (__STRICT_ANSI__) && !defined (__HIDE_FORBIDDEN_NAMES)
24150b7e42Smiod # ifdef __cplusplus
25150b7e42Smiod extern "C" {
26150b7e42Smiod # endif /* __cplusplus */
27150b7e42Smiod extern char *strerror (int,...);
2800bf4279Sespie # define DONT_DECLARE_STRERROR
29150b7e42Smiod # ifdef __cplusplus
30150b7e42Smiod }
31150b7e42Smiod # endif /* __cplusplus */
3200bf4279Sespie # endif
3300bf4279Sespie #endif /* VMS */
3400bf4279Sespie
35150b7e42Smiod
3600bf4279Sespie #ifndef DONT_DECLARE_STRERROR
37150b7e42Smiod # ifdef __cplusplus
38150b7e42Smiod extern "C" {
39150b7e42Smiod # endif /* __cplusplus */
40150b7e42Smiod extern char *strerror (int);
41150b7e42Smiod # ifdef __cplusplus
42150b7e42Smiod }
43150b7e42Smiod # endif /* __cplusplus */
4400bf4279Sespie #endif
4500bf4279Sespie
4600bf4279Sespie /* If strerror returns NULL, we'll format the number into a static buffer. */
4700bf4279Sespie
4800bf4279Sespie #define ERRSTR_FMT "undocumented error #%d"
4900bf4279Sespie static char xstrerror_buf[sizeof ERRSTR_FMT + 20];
5000bf4279Sespie
5100bf4279Sespie /* Like strerror, but result is never a null pointer. */
5200bf4279Sespie
5300bf4279Sespie char *
xstrerror(int errnum)54150b7e42Smiod xstrerror (int errnum)
5500bf4279Sespie {
5600bf4279Sespie char *errstr;
5700bf4279Sespie #ifdef VMS
58150b7e42Smiod char *(*vmslib_strerror) (int,...);
5900bf4279Sespie
6000bf4279Sespie /* Override any possibly-conflicting declaration from system header. */
61150b7e42Smiod vmslib_strerror = (char *(*) (int,...)) strerror;
6200bf4279Sespie /* Second argument matters iff first is EVMSERR, but it's simpler to
6300bf4279Sespie pass it unconditionally. `vaxc$errno' is declared in <errno.h>
6400bf4279Sespie and maintained by the run-time library in parallel to `errno'.
6500bf4279Sespie We assume that `errnum' corresponds to the last value assigned to
6600bf4279Sespie errno by the run-time library, hence vaxc$errno will be relevant. */
6700bf4279Sespie errstr = (*vmslib_strerror) (errnum, vaxc$errno);
6800bf4279Sespie #else
6900bf4279Sespie errstr = strerror (errnum);
7000bf4279Sespie #endif
7100bf4279Sespie
7200bf4279Sespie /* If `errnum' is out of range, result might be NULL. We'll fix that. */
7300bf4279Sespie if (!errstr)
7400bf4279Sespie {
75*c404a200Smiod snprintf (xstrerror_buf, sizeof xstrerror_buf, ERRSTR_FMT, errnum);
7600bf4279Sespie errstr = xstrerror_buf;
7700bf4279Sespie }
7800bf4279Sespie return errstr;
7900bf4279Sespie }
80