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