1169695Skan/* xstrerror.c -- jacket routine for more robust strerror() usage.
2169695Skan   Fri Jun 16 18:30:00 1995  Pat Rankin  <rankin@eql.caltech.edu>
3169695Skan   This code is in the public domain.  */
4169695Skan
5169695Skan/*
6169695Skan
7169695Skan@deftypefn Replacement char* xstrerror (int @var{errnum})
8169695Skan
9169695SkanBehaves exactly like the standard @code{strerror} function, but
10169695Skanwill never return a @code{NULL} pointer.
11169695Skan
12169695Skan@end deftypefn
13169695Skan
14169695Skan*/
15169695Skan
16169695Skan#include <stdio.h>
17169695Skan
18169695Skan#include "config.h"
19169695Skan#include "libiberty.h"
20169695Skan
21169695Skan#ifdef VMS
22169695Skan#  include <errno.h>
23169695Skan#  if !defined (__STRICT_ANSI__) && !defined (__HIDE_FORBIDDEN_NAMES)
24169695Skan#    ifdef __cplusplus
25169695Skanextern "C" {
26169695Skan#    endif /* __cplusplus */
27169695Skanextern char *strerror (int,...);
28169695Skan#    define DONT_DECLARE_STRERROR
29169695Skan#    ifdef __cplusplus
30169695Skan}
31169695Skan#    endif /* __cplusplus */
32169695Skan#  endif
33169695Skan#endif  /* VMS */
34169695Skan
35169695Skan
36169695Skan#ifndef DONT_DECLARE_STRERROR
37169695Skan#  ifdef __cplusplus
38169695Skanextern "C" {
39169695Skan#  endif /* __cplusplus */
40169695Skanextern char *strerror (int);
41169695Skan#  ifdef __cplusplus
42169695Skan}
43169695Skan#  endif /* __cplusplus */
44169695Skan#endif
45169695Skan
46169695Skan/* If strerror returns NULL, we'll format the number into a static buffer.  */
47169695Skan
48169695Skan#define ERRSTR_FMT "undocumented error #%d"
49169695Skanstatic char xstrerror_buf[sizeof ERRSTR_FMT + 20];
50169695Skan
51169695Skan/* Like strerror, but result is never a null pointer.  */
52169695Skan
53169695Skanchar *
54169695Skanxstrerror (int errnum)
55169695Skan{
56169695Skan  char *errstr;
57169695Skan#ifdef VMS
58169695Skan  char *(*vmslib_strerror) (int,...);
59169695Skan
60169695Skan  /* Override any possibly-conflicting declaration from system header.  */
61169695Skan  vmslib_strerror = (char *(*) (int,...)) strerror;
62169695Skan  /* Second argument matters iff first is EVMSERR, but it's simpler to
63169695Skan     pass it unconditionally.  `vaxc$errno' is declared in <errno.h>
64169695Skan     and maintained by the run-time library in parallel to `errno'.
65169695Skan     We assume that `errnum' corresponds to the last value assigned to
66169695Skan     errno by the run-time library, hence vaxc$errno will be relevant.  */
67169695Skan  errstr = (*vmslib_strerror) (errnum, vaxc$errno);
68169695Skan#else
69169695Skan  errstr = strerror (errnum);
70169695Skan#endif
71169695Skan
72169695Skan  /* If `errnum' is out of range, result might be NULL.  We'll fix that.  */
73169695Skan  if (!errstr)
74169695Skan    {
75169695Skan      sprintf (xstrerror_buf, ERRSTR_FMT, errnum);
76169695Skan      errstr = xstrerror_buf;
77169695Skan    }
78169695Skan  return errstr;
79169695Skan}
80