133965Sjdp/* xstrerror.c -- jacket routine for more robust strerror() usage. 233965Sjdp Fri Jun 16 18:30:00 1995 Pat Rankin <rankin@eql.caltech.edu> 333965Sjdp This code is in the public domain. */ 433965Sjdp 589857Sobrien/* 689857Sobrien 789857Sobrien@deftypefn Replacement char* xstrerror (int @var{errnum}) 889857Sobrien 989857SobrienBehaves exactly like the standard @code{strerror} function, but 1089857Sobrienwill never return a @code{NULL} pointer. 1189857Sobrien 1289857Sobrien@end deftypefn 1389857Sobrien 1489857Sobrien*/ 1589857Sobrien 1633965Sjdp#include <stdio.h> 1733965Sjdp 18218822Sdim#include "config.h" 1933965Sjdp#include "libiberty.h" 2033965Sjdp 2133965Sjdp#ifdef VMS 22218822Sdim# include <errno.h> 23218822Sdim# if !defined (__STRICT_ANSI__) && !defined (__HIDE_FORBIDDEN_NAMES) 24218822Sdim# ifdef __cplusplus 25218822Sdimextern "C" { 26218822Sdim# endif /* __cplusplus */ 27218822Sdimextern char *strerror (int,...); 28218822Sdim# define DONT_DECLARE_STRERROR 29218822Sdim# ifdef __cplusplus 30218822Sdim} 31218822Sdim# endif /* __cplusplus */ 32218822Sdim# endif 33218822Sdim#endif /* VMS */ 3433965Sjdp 35218822Sdim 3633965Sjdp#ifndef DONT_DECLARE_STRERROR 37218822Sdim# ifdef __cplusplus 38218822Sdimextern "C" { 39218822Sdim# endif /* __cplusplus */ 40218822Sdimextern char *strerror (int); 41218822Sdim# ifdef __cplusplus 42218822Sdim} 43218822Sdim# endif /* __cplusplus */ 4433965Sjdp#endif 4533965Sjdp 4633965Sjdp/* If strerror returns NULL, we'll format the number into a static buffer. */ 4733965Sjdp 4833965Sjdp#define ERRSTR_FMT "undocumented error #%d" 4933965Sjdpstatic char xstrerror_buf[sizeof ERRSTR_FMT + 20]; 5033965Sjdp 5133965Sjdp/* Like strerror, but result is never a null pointer. */ 5233965Sjdp 5333965Sjdpchar * 54218822Sdimxstrerror (int errnum) 5533965Sjdp{ 5633965Sjdp char *errstr; 5733965Sjdp#ifdef VMS 58218822Sdim char *(*vmslib_strerror) (int,...); 5933965Sjdp 6033965Sjdp /* Override any possibly-conflicting declaration from system header. */ 61218822Sdim vmslib_strerror = (char *(*) (int,...)) strerror; 6233965Sjdp /* Second argument matters iff first is EVMSERR, but it's simpler to 6333965Sjdp pass it unconditionally. `vaxc$errno' is declared in <errno.h> 6433965Sjdp and maintained by the run-time library in parallel to `errno'. 6533965Sjdp We assume that `errnum' corresponds to the last value assigned to 6633965Sjdp errno by the run-time library, hence vaxc$errno will be relevant. */ 6733965Sjdp errstr = (*vmslib_strerror) (errnum, vaxc$errno); 6833965Sjdp#else 6933965Sjdp errstr = strerror (errnum); 7033965Sjdp#endif 7133965Sjdp 7233965Sjdp /* If `errnum' is out of range, result might be NULL. We'll fix that. */ 7333965Sjdp if (!errstr) 7433965Sjdp { 7533965Sjdp sprintf (xstrerror_buf, ERRSTR_FMT, errnum); 7633965Sjdp errstr = xstrerror_buf; 7733965Sjdp } 7833965Sjdp return errstr; 7933965Sjdp} 80