2005-11-19 23:59:16 +01:00
|
|
|
// note: this is called lib_errors.cpp because we have another
|
|
|
|
// errors.cpp; the MS linker isn't smart enough to deal with
|
|
|
|
// object files of the same name but in different paths.
|
|
|
|
|
2005-11-19 19:12:16 +01:00
|
|
|
#include "precompiled.h"
|
|
|
|
|
2005-11-19 23:59:16 +01:00
|
|
|
#include "lib_errors.h"
|
2005-11-19 19:12:16 +01:00
|
|
|
#include "sysdep/sysdep.h"
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h> // abs
|
|
|
|
|
|
|
|
|
|
|
|
static const char* lib_error_description(int err)
|
|
|
|
{
|
|
|
|
// not in our range
|
|
|
|
if(!(ERR_MIN <= abs(err) && abs(err) < ERR_MAX))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
switch(err)
|
|
|
|
{
|
|
|
|
#define ERR(err, id, str) case id: return str;
|
2005-11-19 23:59:16 +01:00
|
|
|
#include "lib_errors.h"
|
2005-11-19 19:12:16 +01:00
|
|
|
default: return "Unknown lib error";
|
|
|
|
}
|
|
|
|
UNREACHABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-12-07 04:38:39 +01:00
|
|
|
// generate textual description of an error code.
|
|
|
|
// stores up to <max_chars> in the given buffer.
|
|
|
|
// <err> can be one of the above error codes, POSIX ENOENT etc., or
|
|
|
|
// an OS-specific errors. if unknown, the string will be something like
|
|
|
|
// "Unknown error (65536, 0x10000)".
|
2005-11-19 19:12:16 +01:00
|
|
|
void error_description_r(int err, char* buf, size_t max_chars)
|
|
|
|
{
|
|
|
|
// lib error
|
|
|
|
const char* str = lib_error_description(err);
|
|
|
|
if(str)
|
|
|
|
{
|
|
|
|
// <err> was one of our error codes (chosen so as not to conflict
|
|
|
|
// with any others), so we're done.
|
|
|
|
strcpy_s(buf, max_chars, str);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Win32 GetLastError and errno both define values in [0,100).
|
|
|
|
// what we'll do is always try the OS-specific translation,
|
|
|
|
// add libc's interpretation if <err> is a valid errno, and
|
|
|
|
// output "Unknown" if none of the above succeeds.
|
|
|
|
const bool should_display_libc_err = (0 <= err && err < sys_nerr);
|
|
|
|
bool have_output = false;
|
|
|
|
|
|
|
|
// OS-specific error
|
|
|
|
if(sys_error_description_r(err, buf, max_chars) == 0) // success
|
|
|
|
{
|
|
|
|
have_output = true;
|
|
|
|
|
|
|
|
// add a separator text before libc description
|
|
|
|
if(should_display_libc_err)
|
|
|
|
strcat_s(buf, max_chars, "; libc err=");
|
|
|
|
}
|
|
|
|
|
|
|
|
// libc error
|
|
|
|
if(should_display_libc_err)
|
|
|
|
{
|
|
|
|
strcat_s(buf, max_chars, strerror(err));
|
|
|
|
// note: we are sure to get meaningful output (not just "unknown")
|
|
|
|
// because err < sys_nerr.
|
|
|
|
have_output = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// fallback
|
|
|
|
if(!have_output)
|
|
|
|
snprintf(buf, max_chars, "Unknown error (%d, 0x%X)", err, err);
|
|
|
|
}
|