1219820Sjeff/* xstrerror.c -- jacket routine for more robust strerror() usage. 2219820Sjeff Fri Jun 16 18:30:00 1995 Pat Rankin <rankin@eql.caltech.edu> 3219820Sjeff This code is in the public domain. */ 4219820Sjeff 5219820Sjeff/* 6219820Sjeff 7219820Sjeff@deftypefn Replacement char* xstrerror (int @var{errnum}) 8219820Sjeff 9219820SjeffBehaves exactly like the standard @code{strerror} function, but 10219820Sjeffwill never return a @code{NULL} pointer. 11219820Sjeff 12219820Sjeff@end deftypefn 13219820Sjeff 14219820Sjeff*/ 15219820Sjeff 16219820Sjeff#include <stdio.h> 17219820Sjeff 18219820Sjeff#include "config.h" 19219820Sjeff#include "libiberty.h" 20219820Sjeff 21219820Sjeff#ifdef VMS 22219820Sjeff# include <errno.h> 23219820Sjeff# if !defined (__STRICT_ANSI__) && !defined (__HIDE_FORBIDDEN_NAMES) 24219820Sjeff# ifdef __cplusplus 25219820Sjeffextern "C" { 26219820Sjeff# endif /* __cplusplus */ 27219820Sjeffextern char *strerror (int,...); 28219820Sjeff# define DONT_DECLARE_STRERROR 29219820Sjeff# ifdef __cplusplus 30219820Sjeff} 31219820Sjeff# endif /* __cplusplus */ 32219820Sjeff# endif 33219820Sjeff#endif /* VMS */ 34219820Sjeff 35219820Sjeff 36219820Sjeff#ifndef DONT_DECLARE_STRERROR 37219820Sjeff# ifdef __cplusplus 38219820Sjeffextern "C" { 39219820Sjeff# endif /* __cplusplus */ 40219820Sjeffextern char *strerror (int); 41219820Sjeff# ifdef __cplusplus 42219820Sjeff} 43219820Sjeff# endif /* __cplusplus */ 44219820Sjeff#endif 45219820Sjeff 46219820Sjeff/* If strerror returns NULL, we'll format the number into a static buffer. */ 47219820Sjeff 48219820Sjeff#define ERRSTR_FMT "undocumented error #%d" 49219820Sjeffstatic char xstrerror_buf[sizeof ERRSTR_FMT + 20]; 50219820Sjeff 51219820Sjeff/* Like strerror, but result is never a null pointer. */ 52219820Sjeff 53219820Sjeffchar * 54219820Sjeffxstrerror (int errnum) 55219820Sjeff{ 56219820Sjeff char *errstr; 57219820Sjeff#ifdef VMS 58219820Sjeff char *(*vmslib_strerror) (int,...); 59219820Sjeff 60219820Sjeff /* Override any possibly-conflicting declaration from system header. */ 61219820Sjeff vmslib_strerror = (char *(*) (int,...)) strerror; 62219820Sjeff /* Second argument matters iff first is EVMSERR, but it's simpler to 63219820Sjeff pass it unconditionally. `vaxc$errno' is declared in <errno.h> 64219820Sjeff and maintained by the run-time library in parallel to `errno'. 65219820Sjeff We assume that `errnum' corresponds to the last value assigned to 66219820Sjeff errno by the run-time library, hence vaxc$errno will be relevant. */ 67219820Sjeff errstr = (*vmslib_strerror) (errnum, vaxc$errno); 68219820Sjeff#else 69219820Sjeff errstr = strerror (errnum); 70219820Sjeff#endif 71219820Sjeff 72219820Sjeff /* If `errnum' is out of range, result might be NULL. We'll fix that. */ 73219820Sjeff if (!errstr) 74219820Sjeff { 75219820Sjeff sprintf (xstrerror_buf, ERRSTR_FMT, errnum); 76219820Sjeff errstr = xstrerror_buf; 77219820Sjeff } 78219820Sjeff return errstr; 79219820Sjeff} 80219820Sjeff