1*1debfc3dSmrg /* xstrerror.c -- jacket routine for more robust strerror() usage.
2*1debfc3dSmrg Fri Jun 16 18:30:00 1995 Pat Rankin <rankin@eql.caltech.edu>
3*1debfc3dSmrg This code is in the public domain. */
4*1debfc3dSmrg
5*1debfc3dSmrg /*
6*1debfc3dSmrg
7*1debfc3dSmrg @deftypefn Replacement char* xstrerror (int @var{errnum})
8*1debfc3dSmrg
9*1debfc3dSmrg Behaves exactly like the standard @code{strerror} function, but
10*1debfc3dSmrg will never return a @code{NULL} pointer.
11*1debfc3dSmrg
12*1debfc3dSmrg @end deftypefn
13*1debfc3dSmrg
14*1debfc3dSmrg */
15*1debfc3dSmrg
16*1debfc3dSmrg #include <stdio.h>
17*1debfc3dSmrg
18*1debfc3dSmrg #include "config.h"
19*1debfc3dSmrg #include "libiberty.h"
20*1debfc3dSmrg
21*1debfc3dSmrg #ifdef VMS
22*1debfc3dSmrg # include <errno.h>
23*1debfc3dSmrg # if !defined (__STRICT_ANSI__) && !defined (__HIDE_FORBIDDEN_NAMES)
24*1debfc3dSmrg # ifdef __cplusplus
25*1debfc3dSmrg extern "C" {
26*1debfc3dSmrg # endif /* __cplusplus */
27*1debfc3dSmrg extern char *strerror (int,...);
28*1debfc3dSmrg # define DONT_DECLARE_STRERROR
29*1debfc3dSmrg # ifdef __cplusplus
30*1debfc3dSmrg }
31*1debfc3dSmrg # endif /* __cplusplus */
32*1debfc3dSmrg # endif
33*1debfc3dSmrg #endif /* VMS */
34*1debfc3dSmrg
35*1debfc3dSmrg
36*1debfc3dSmrg #ifndef DONT_DECLARE_STRERROR
37*1debfc3dSmrg # ifdef __cplusplus
38*1debfc3dSmrg extern "C" {
39*1debfc3dSmrg # endif /* __cplusplus */
40*1debfc3dSmrg extern char *strerror (int);
41*1debfc3dSmrg # ifdef __cplusplus
42*1debfc3dSmrg }
43*1debfc3dSmrg # endif /* __cplusplus */
44*1debfc3dSmrg #endif
45*1debfc3dSmrg
46*1debfc3dSmrg /* If strerror returns NULL, we'll format the number into a static buffer. */
47*1debfc3dSmrg
48*1debfc3dSmrg #define ERRSTR_FMT "undocumented error #%d"
49*1debfc3dSmrg static char xstrerror_buf[sizeof ERRSTR_FMT + 20];
50*1debfc3dSmrg
51*1debfc3dSmrg /* Like strerror, but result is never a null pointer. */
52*1debfc3dSmrg
53*1debfc3dSmrg char *
xstrerror(int errnum)54*1debfc3dSmrg xstrerror (int errnum)
55*1debfc3dSmrg {
56*1debfc3dSmrg char *errstr;
57*1debfc3dSmrg #ifdef VMS
58*1debfc3dSmrg char *(*vmslib_strerror) (int,...);
59*1debfc3dSmrg
60*1debfc3dSmrg /* Override any possibly-conflicting declaration from system header. */
61*1debfc3dSmrg vmslib_strerror = (char *(*) (int,...)) strerror;
62*1debfc3dSmrg /* Second argument matters iff first is EVMSERR, but it's simpler to
63*1debfc3dSmrg pass it unconditionally. `vaxc$errno' is declared in <errno.h>
64*1debfc3dSmrg and maintained by the run-time library in parallel to `errno'.
65*1debfc3dSmrg We assume that `errnum' corresponds to the last value assigned to
66*1debfc3dSmrg errno by the run-time library, hence vaxc$errno will be relevant. */
67*1debfc3dSmrg errstr = (*vmslib_strerror) (errnum, vaxc$errno);
68*1debfc3dSmrg #else
69*1debfc3dSmrg errstr = strerror (errnum);
70*1debfc3dSmrg #endif
71*1debfc3dSmrg
72*1debfc3dSmrg /* If `errnum' is out of range, result might be NULL. We'll fix that. */
73*1debfc3dSmrg if (!errstr)
74*1debfc3dSmrg {
75*1debfc3dSmrg sprintf (xstrerror_buf, ERRSTR_FMT, errnum);
76*1debfc3dSmrg errstr = xstrerror_buf;
77*1debfc3dSmrg }
78*1debfc3dSmrg return errstr;
79*1debfc3dSmrg }
80