diff -rpcd a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c *** a/src/backend/utils/error/elog.c 2013-06-25 03:55:41.000000000 +0900 --- b/src/backend/utils/error/elog.c 2013-09-09 15:56:28.000000000 +0900 *************** static void log_line_prefix(StringInfo b *** 170,175 **** --- 170,176 ---- 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 *get_errno_symbol(int errnum); static const char *useful_strerror(int errnum); static const char *error_severity(int elevel); static void append_with_tabs(StringInfo buf, const char *str); *************** expand_fmt_string(const char *fmt, Error *** 2921,2933 **** } /* * A slightly cleaned-up version of strerror() */ static const char * useful_strerror(int errnum) { ! /* this buffer is only used if errno has a bogus value */ static char errorstr_buf[48]; const char *str; --- 2922,3080 ---- } + static const struct + { + int errnum; + char *symbol; + } errno_symbols[] = + + { + { + EINVAL, "EINVAL" + }, + { + ENOENT, "ENOENT" + }, + { + EMFILE, "EMFILE" + }, + { + EACCES, "EACCES" + }, + { + EBADF, "EBADF" + }, + { + ENOMEM, "ENOMEM" + }, + { + E2BIG, "E2BIG" + }, + { + ENOEXEC, "ENOEXEC" + }, + { + EXDEV, "EXDEV" + }, + { + EEXIST, "EEXIST" + }, + { + EPIPE, "EPIPE" + }, + { + ENOSPC, "ENOSPC" + }, + { + ECHILD, "ECHILD" + }, + { + ENOTEMPTY, "ENOTEMPTY" + }, + { + EAFNOSUPPORT, "EAFNOSUPPORT" + }, + { + ECONNREFUSED, "ECONNREFUSED" + }, + { + EDEADLK, "EDEADLK" + }, + { + EDOM, "EDOM" + }, + { + EIDRM, "EIDRM" + }, + { + EINTR, "EINTR" + }, + { + EIO, "EIO" + }, + { + EISDIR, "EISDIR" + }, + { + EMSGSIZE, "EMSGSIZE" + }, + { + ENFILE, "ENFILE" + }, + { + ENOBUFS, "ENOBUFS" + }, + { + ENOSYS, "ENOSYS" + }, + { + ENOTDIR, "ENOTDIR" + }, + { + EOPNOTSUPP, "EOPNOTSUPP" + }, + { + EPERM, "EPERM" + }, + { + EPROTONOSUPPORT, "EPROTONOSUPPORT" + }, + { + ERANGE, "ERANGE" + }, + { + ESRCH, "ESRCH" + }, + #ifdef ECONNRESET + { + ECONNRESET, "ECONNRESET" + }, + #endif + #ifdef EINPROGRESS + { + EINPROGRESS, "EINPROGRESS" + }, + #endif + #ifdef EROFS + { + EROFS, "EROFS" + }, + #endif + #ifdef EAGAIN + { + EAGAIN, "EAGAIN" + }, + #endif + #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) + { + EWOULDBLOCK, "EWOULDBLOCK" + } + #endif + }; + + /* + * Returns a symbol (e.g. ENOENT) for an errno value. + * Returns NULL if no corresponding symbol is found. + */ + static const char * + get_errno_symbol(int errnum) + { + int i; + + for (i = 0; i < lengthof(errno_symbols); i++) + if (errno_symbols[i].errnum == errnum) + return errno_symbols[i].symbol; + + return NULL; + } + /* * A slightly cleaned-up version of strerror() */ static const char * useful_strerror(int errnum) { ! /* this buffer is only used if strerror() fails to return a useful string */ static char errorstr_buf[48]; const char *str; *************** useful_strerror(int errnum) *** 2940,2948 **** /* * Some strerror()s return an empty string for out-of-range errno. This is ! * ANSI C spec compliant, but not exactly useful. */ ! if (str == NULL || *str == '\0') { snprintf(errorstr_buf, sizeof(errorstr_buf), /*------ --- 3087,3099 ---- /* * Some strerror()s return an empty string for out-of-range errno. This is ! * ANSI C spec compliant, but not exactly useful. glibc's strerror() ! * returns "???" if it cannot transcode a message to the codeset specified ! * by LC_CTYPE. */ ! if (str == NULL || *str == '\0' || *str == '?') ! str = get_errno_symbol(errnum); ! if (str == NULL) { snprintf(errorstr_buf, sizeof(errorstr_buf), /*------