mirror of
https://github.com/postgres/postgres.git
synced 2025-11-15 03:41:20 +03:00
Be more robust when strerror() doesn't give a useful result.
Back-patch commits8e68816cc2and8dace66e07into the stable branches. Buildfarm testing revealed no great portability surprises, and it seems useful to have this robustness improvement in all branches.
This commit is contained in:
@@ -170,6 +170,7 @@ static void send_message_to_server_log(ErrorData *edata);
|
||||
static void send_message_to_frontend(ErrorData *edata);
|
||||
static char *expand_fmt_string(const char *fmt, ErrorData *edata);
|
||||
static const char *useful_strerror(int errnum);
|
||||
static const char *get_errno_symbol(int errnum);
|
||||
static const char *error_severity(int elevel);
|
||||
static void append_with_tabs(StringInfo buf, const char *str);
|
||||
static bool is_log_level_output(int elevel, int log_min_level);
|
||||
@@ -2784,7 +2785,7 @@ expand_fmt_string(const char *fmt, ErrorData *edata)
|
||||
static const char *
|
||||
useful_strerror(int errnum)
|
||||
{
|
||||
/* this buffer is only used if errno has a bogus value */
|
||||
/* this buffer is only used if strerror() and get_errno_symbol() fail */
|
||||
static char errorstr_buf[48];
|
||||
const char *str;
|
||||
|
||||
@@ -2796,10 +2797,16 @@ useful_strerror(int errnum)
|
||||
str = strerror(errnum);
|
||||
|
||||
/*
|
||||
* Some strerror()s return an empty string for out-of-range errno. This is
|
||||
* ANSI C spec compliant, but not exactly useful.
|
||||
* Some strerror()s return an empty string for out-of-range errno. This
|
||||
* is ANSI C spec compliant, but not exactly useful. Also, we may get
|
||||
* back strings of question marks if libc cannot transcode the message to
|
||||
* the codeset specified by LC_CTYPE. If we get nothing useful, first try
|
||||
* get_errno_symbol(), and if that fails, print the numeric errno.
|
||||
*/
|
||||
if (str == NULL || *str == '\0')
|
||||
if (str == NULL || *str == '\0' || *str == '?')
|
||||
str = get_errno_symbol(errnum);
|
||||
|
||||
if (str == NULL)
|
||||
{
|
||||
snprintf(errorstr_buf, sizeof(errorstr_buf),
|
||||
/*------
|
||||
@@ -2812,6 +2819,178 @@ useful_strerror(int errnum)
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a symbol (e.g. "ENOENT") for an errno code.
|
||||
* Returns NULL if the code is unrecognized.
|
||||
*/
|
||||
static const char *
|
||||
get_errno_symbol(int errnum)
|
||||
{
|
||||
switch (errnum)
|
||||
{
|
||||
case E2BIG:
|
||||
return "E2BIG";
|
||||
case EACCES:
|
||||
return "EACCES";
|
||||
#ifdef EADDRINUSE
|
||||
case EADDRINUSE:
|
||||
return "EADDRINUSE";
|
||||
#endif
|
||||
#ifdef EADDRNOTAVAIL
|
||||
case EADDRNOTAVAIL:
|
||||
return "EADDRNOTAVAIL";
|
||||
#endif
|
||||
case EAFNOSUPPORT:
|
||||
return "EAFNOSUPPORT";
|
||||
#ifdef EAGAIN
|
||||
case EAGAIN:
|
||||
return "EAGAIN";
|
||||
#endif
|
||||
#ifdef EALREADY
|
||||
case EALREADY:
|
||||
return "EALREADY";
|
||||
#endif
|
||||
case EBADF:
|
||||
return "EBADF";
|
||||
#ifdef EBADMSG
|
||||
case EBADMSG:
|
||||
return "EBADMSG";
|
||||
#endif
|
||||
case EBUSY:
|
||||
return "EBUSY";
|
||||
case ECHILD:
|
||||
return "ECHILD";
|
||||
#ifdef ECONNABORTED
|
||||
case ECONNABORTED:
|
||||
return "ECONNABORTED";
|
||||
#endif
|
||||
case ECONNREFUSED:
|
||||
return "ECONNREFUSED";
|
||||
#ifdef ECONNRESET
|
||||
case ECONNRESET:
|
||||
return "ECONNRESET";
|
||||
#endif
|
||||
case EDEADLK:
|
||||
return "EDEADLK";
|
||||
case EDOM:
|
||||
return "EDOM";
|
||||
case EEXIST:
|
||||
return "EEXIST";
|
||||
case EFAULT:
|
||||
return "EFAULT";
|
||||
case EFBIG:
|
||||
return "EFBIG";
|
||||
#ifdef EHOSTUNREACH
|
||||
case EHOSTUNREACH:
|
||||
return "EHOSTUNREACH";
|
||||
#endif
|
||||
case EIDRM:
|
||||
return "EIDRM";
|
||||
case EINPROGRESS:
|
||||
return "EINPROGRESS";
|
||||
case EINTR:
|
||||
return "EINTR";
|
||||
case EINVAL:
|
||||
return "EINVAL";
|
||||
case EIO:
|
||||
return "EIO";
|
||||
#ifdef EISCONN
|
||||
case EISCONN:
|
||||
return "EISCONN";
|
||||
#endif
|
||||
case EISDIR:
|
||||
return "EISDIR";
|
||||
#ifdef ELOOP
|
||||
case ELOOP:
|
||||
return "ELOOP";
|
||||
#endif
|
||||
case EMFILE:
|
||||
return "EMFILE";
|
||||
case EMLINK:
|
||||
return "EMLINK";
|
||||
case EMSGSIZE:
|
||||
return "EMSGSIZE";
|
||||
case ENAMETOOLONG:
|
||||
return "ENAMETOOLONG";
|
||||
case ENFILE:
|
||||
return "ENFILE";
|
||||
case ENOBUFS:
|
||||
return "ENOBUFS";
|
||||
case ENODEV:
|
||||
return "ENODEV";
|
||||
case ENOENT:
|
||||
return "ENOENT";
|
||||
case ENOEXEC:
|
||||
return "ENOEXEC";
|
||||
case ENOMEM:
|
||||
return "ENOMEM";
|
||||
case ENOSPC:
|
||||
return "ENOSPC";
|
||||
case ENOSYS:
|
||||
return "ENOSYS";
|
||||
#ifdef ENOTCONN
|
||||
case ENOTCONN:
|
||||
return "ENOTCONN";
|
||||
#endif
|
||||
case ENOTDIR:
|
||||
return "ENOTDIR";
|
||||
#if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST) /* same code on AIX */
|
||||
case ENOTEMPTY:
|
||||
return "ENOTEMPTY";
|
||||
#endif
|
||||
#ifdef ENOTSOCK
|
||||
case ENOTSOCK:
|
||||
return "ENOTSOCK";
|
||||
#endif
|
||||
#ifdef ENOTSUP
|
||||
case ENOTSUP:
|
||||
return "ENOTSUP";
|
||||
#endif
|
||||
case ENOTTY:
|
||||
return "ENOTTY";
|
||||
case ENXIO:
|
||||
return "ENXIO";
|
||||
#if defined(EOPNOTSUPP) && (!defined(ENOTSUP) || (EOPNOTSUPP != ENOTSUP))
|
||||
case EOPNOTSUPP:
|
||||
return "EOPNOTSUPP";
|
||||
#endif
|
||||
#ifdef EOVERFLOW
|
||||
case EOVERFLOW:
|
||||
return "EOVERFLOW";
|
||||
#endif
|
||||
case EPERM:
|
||||
return "EPERM";
|
||||
case EPIPE:
|
||||
return "EPIPE";
|
||||
case EPROTONOSUPPORT:
|
||||
return "EPROTONOSUPPORT";
|
||||
case ERANGE:
|
||||
return "ERANGE";
|
||||
#ifdef EROFS
|
||||
case EROFS:
|
||||
return "EROFS";
|
||||
#endif
|
||||
case ESRCH:
|
||||
return "ESRCH";
|
||||
#ifdef ETIMEDOUT
|
||||
case ETIMEDOUT:
|
||||
return "ETIMEDOUT";
|
||||
#endif
|
||||
#ifdef ETXTBSY
|
||||
case ETXTBSY:
|
||||
return "ETXTBSY";
|
||||
#endif
|
||||
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
|
||||
case EWOULDBLOCK:
|
||||
return "EWOULDBLOCK";
|
||||
#endif
|
||||
case EXDEV:
|
||||
return "EXDEV";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* error_severity --- get localized string representing elevel
|
||||
|
||||
Reference in New Issue
Block a user