@@ -153,6 +153,7 @@ static void send_message_to_server_log(ErrorData *edata);
153153static void send_message_to_frontend (ErrorData * edata );
154154static char * expand_fmt_string (const char * fmt ,ErrorData * edata );
155155static const char * useful_strerror (int errnum );
156+ static const char * get_errno_symbol (int errnum );
156157static const char * error_severity (int elevel );
157158static void append_with_tabs (StringInfo buf ,const char * str );
158159static bool is_log_level_output (int elevel ,int log_min_level );
@@ -2650,7 +2651,7 @@ expand_fmt_string(const char *fmt, ErrorData *edata)
26502651static const char *
26512652useful_strerror (int errnum )
26522653{
2653- /* this buffer is only used iferrno has a bogus value */
2654+ /* this buffer is only used ifstrerror() and get_errno_symbol() fail */
26542655static char errorstr_buf [48 ];
26552656const char * str ;
26562657
@@ -2662,10 +2663,16 @@ useful_strerror(int errnum)
26622663str = strerror (errnum );
26632664
26642665/*
2665- * Some strerror()s return an empty string for out-of-range errno. This is
2666- * ANSI C spec compliant, but not exactly useful.
2666+ * Some strerror()s return an empty string for out-of-range errno.This
2667+ * is ANSI C spec compliant, but not exactly useful. Also, we may get
2668+ * back strings of question marks if libc cannot transcode the message to
2669+ * the codeset specified by LC_CTYPE. If we get nothing useful, first try
2670+ * get_errno_symbol(), and if that fails, print the numeric errno.
26672671 */
2668- if (str == NULL || * str == '\0' )
2672+ if (str == NULL || * str == '\0' || * str == '?' )
2673+ str = get_errno_symbol (errnum );
2674+
2675+ if (str == NULL )
26692676{
26702677snprintf (errorstr_buf ,sizeof (errorstr_buf ),
26712678/*------
@@ -2678,6 +2685,178 @@ useful_strerror(int errnum)
26782685return str ;
26792686}
26802687
2688+ /*
2689+ * Returns a symbol (e.g. "ENOENT") for an errno code.
2690+ * Returns NULL if the code is unrecognized.
2691+ */
2692+ static const char *
2693+ get_errno_symbol (int errnum )
2694+ {
2695+ switch (errnum )
2696+ {
2697+ case E2BIG :
2698+ return "E2BIG" ;
2699+ case EACCES :
2700+ return "EACCES" ;
2701+ #ifdef EADDRINUSE
2702+ case EADDRINUSE :
2703+ return "EADDRINUSE" ;
2704+ #endif
2705+ #ifdef EADDRNOTAVAIL
2706+ case EADDRNOTAVAIL :
2707+ return "EADDRNOTAVAIL" ;
2708+ #endif
2709+ case EAFNOSUPPORT :
2710+ return "EAFNOSUPPORT" ;
2711+ #ifdef EAGAIN
2712+ case EAGAIN :
2713+ return "EAGAIN" ;
2714+ #endif
2715+ #ifdef EALREADY
2716+ case EALREADY :
2717+ return "EALREADY" ;
2718+ #endif
2719+ case EBADF :
2720+ return "EBADF" ;
2721+ #ifdef EBADMSG
2722+ case EBADMSG :
2723+ return "EBADMSG" ;
2724+ #endif
2725+ case EBUSY :
2726+ return "EBUSY" ;
2727+ case ECHILD :
2728+ return "ECHILD" ;
2729+ #ifdef ECONNABORTED
2730+ case ECONNABORTED :
2731+ return "ECONNABORTED" ;
2732+ #endif
2733+ case ECONNREFUSED :
2734+ return "ECONNREFUSED" ;
2735+ #ifdef ECONNRESET
2736+ case ECONNRESET :
2737+ return "ECONNRESET" ;
2738+ #endif
2739+ case EDEADLK :
2740+ return "EDEADLK" ;
2741+ case EDOM :
2742+ return "EDOM" ;
2743+ case EEXIST :
2744+ return "EEXIST" ;
2745+ case EFAULT :
2746+ return "EFAULT" ;
2747+ case EFBIG :
2748+ return "EFBIG" ;
2749+ #ifdef EHOSTUNREACH
2750+ case EHOSTUNREACH :
2751+ return "EHOSTUNREACH" ;
2752+ #endif
2753+ case EIDRM :
2754+ return "EIDRM" ;
2755+ case EINPROGRESS :
2756+ return "EINPROGRESS" ;
2757+ case EINTR :
2758+ return "EINTR" ;
2759+ case EINVAL :
2760+ return "EINVAL" ;
2761+ case EIO :
2762+ return "EIO" ;
2763+ #ifdef EISCONN
2764+ case EISCONN :
2765+ return "EISCONN" ;
2766+ #endif
2767+ case EISDIR :
2768+ return "EISDIR" ;
2769+ #ifdef ELOOP
2770+ case ELOOP :
2771+ return "ELOOP" ;
2772+ #endif
2773+ case EMFILE :
2774+ return "EMFILE" ;
2775+ case EMLINK :
2776+ return "EMLINK" ;
2777+ case EMSGSIZE :
2778+ return "EMSGSIZE" ;
2779+ case ENAMETOOLONG :
2780+ return "ENAMETOOLONG" ;
2781+ case ENFILE :
2782+ return "ENFILE" ;
2783+ case ENOBUFS :
2784+ return "ENOBUFS" ;
2785+ case ENODEV :
2786+ return "ENODEV" ;
2787+ case ENOENT :
2788+ return "ENOENT" ;
2789+ case ENOEXEC :
2790+ return "ENOEXEC" ;
2791+ case ENOMEM :
2792+ return "ENOMEM" ;
2793+ case ENOSPC :
2794+ return "ENOSPC" ;
2795+ case ENOSYS :
2796+ return "ENOSYS" ;
2797+ #ifdef ENOTCONN
2798+ case ENOTCONN :
2799+ return "ENOTCONN" ;
2800+ #endif
2801+ case ENOTDIR :
2802+ return "ENOTDIR" ;
2803+ #if defined(ENOTEMPTY )&& (ENOTEMPTY != EEXIST )/* same code on AIX */
2804+ case ENOTEMPTY :
2805+ return "ENOTEMPTY" ;
2806+ #endif
2807+ #ifdef ENOTSOCK
2808+ case ENOTSOCK :
2809+ return "ENOTSOCK" ;
2810+ #endif
2811+ #ifdef ENOTSUP
2812+ case ENOTSUP :
2813+ return "ENOTSUP" ;
2814+ #endif
2815+ case ENOTTY :
2816+ return "ENOTTY" ;
2817+ case ENXIO :
2818+ return "ENXIO" ;
2819+ #if defined(EOPNOTSUPP )&& (!defined(ENOTSUP )|| (EOPNOTSUPP != ENOTSUP ))
2820+ case EOPNOTSUPP :
2821+ return "EOPNOTSUPP" ;
2822+ #endif
2823+ #ifdef EOVERFLOW
2824+ case EOVERFLOW :
2825+ return "EOVERFLOW" ;
2826+ #endif
2827+ case EPERM :
2828+ return "EPERM" ;
2829+ case EPIPE :
2830+ return "EPIPE" ;
2831+ case EPROTONOSUPPORT :
2832+ return "EPROTONOSUPPORT" ;
2833+ case ERANGE :
2834+ return "ERANGE" ;
2835+ #ifdef EROFS
2836+ case EROFS :
2837+ return "EROFS" ;
2838+ #endif
2839+ case ESRCH :
2840+ return "ESRCH" ;
2841+ #ifdef ETIMEDOUT
2842+ case ETIMEDOUT :
2843+ return "ETIMEDOUT" ;
2844+ #endif
2845+ #ifdef ETXTBSY
2846+ case ETXTBSY :
2847+ return "ETXTBSY" ;
2848+ #endif
2849+ #if defined(EWOULDBLOCK )&& (!defined(EAGAIN )|| (EWOULDBLOCK != EAGAIN ))
2850+ case EWOULDBLOCK :
2851+ return "EWOULDBLOCK" ;
2852+ #endif
2853+ case EXDEV :
2854+ return "EXDEV" ;
2855+ }
2856+
2857+ return NULL ;
2858+ }
2859+
26812860
26822861/*
26832862 * error_severity --- get localized string representing elevel