@@ -172,6 +172,7 @@ static void send_message_to_server_log(ErrorData *edata);
172
172
static void send_message_to_frontend (ErrorData * edata );
173
173
static char * expand_fmt_string (const char * fmt , ErrorData * edata );
174
174
static const char * useful_strerror (int errnum );
175
+ static const char * get_errno_symbol (int errnum );
175
176
static const char * error_severity (int elevel );
176
177
static void append_with_tabs (StringInfo buf , const char * str );
177
178
static bool is_log_level_output (int elevel , int log_min_level );
@@ -2928,7 +2929,7 @@ expand_fmt_string(const char *fmt, ErrorData *edata)
2928
2929
static const char *
2929
2930
useful_strerror (int errnum )
2930
2931
{
2931
- /* this buffer is only used if errno has a bogus value */
2932
+ /* this buffer is only used if strerror() and get_errno_symbol() fail */
2932
2933
static char errorstr_buf [48 ];
2933
2934
const char * str ;
2934
2935
@@ -2940,10 +2941,16 @@ useful_strerror(int errnum)
2940
2941
str = strerror (errnum );
2941
2942
2942
2943
/*
2943
- * Some strerror()s return an empty string for out-of-range errno. This is
2944
- * ANSI C spec compliant, but not exactly useful.
2944
+ * Some strerror()s return an empty string for out-of-range errno. This
2945
+ * is ANSI C spec compliant, but not exactly useful. Also, we may get
2946
+ * back strings of question marks if libc cannot transcode the message to
2947
+ * the codeset specified by LC_CTYPE. If we get nothing useful, first try
2948
+ * get_errno_symbol(), and if that fails, print the numeric errno.
2945
2949
*/
2946
- if (str == NULL || * str == '\0' )
2950
+ if (str == NULL || * str == '\0' || * str == '?' )
2951
+ str = get_errno_symbol (errnum );
2952
+
2953
+ if (str == NULL )
2947
2954
{
2948
2955
snprintf (errorstr_buf , sizeof (errorstr_buf ),
2949
2956
/*------
@@ -2956,6 +2963,178 @@ useful_strerror(int errnum)
2956
2963
return str ;
2957
2964
}
2958
2965
2966
+ /*
2967
+ * Returns a symbol (e.g. "ENOENT") for an errno code.
2968
+ * Returns NULL if the code is unrecognized.
2969
+ */
2970
+ static const char *
2971
+ get_errno_symbol (int errnum )
2972
+ {
2973
+ switch (errnum )
2974
+ {
2975
+ case E2BIG :
2976
+ return "E2BIG" ;
2977
+ case EACCES :
2978
+ return "EACCES" ;
2979
+ #ifdef EADDRINUSE
2980
+ case EADDRINUSE :
2981
+ return "EADDRINUSE" ;
2982
+ #endif
2983
+ #ifdef EADDRNOTAVAIL
2984
+ case EADDRNOTAVAIL :
2985
+ return "EADDRNOTAVAIL" ;
2986
+ #endif
2987
+ case EAFNOSUPPORT :
2988
+ return "EAFNOSUPPORT" ;
2989
+ #ifdef EAGAIN
2990
+ case EAGAIN :
2991
+ return "EAGAIN" ;
2992
+ #endif
2993
+ #ifdef EALREADY
2994
+ case EALREADY :
2995
+ return "EALREADY" ;
2996
+ #endif
2997
+ case EBADF :
2998
+ return "EBADF" ;
2999
+ #ifdef EBADMSG
3000
+ case EBADMSG :
3001
+ return "EBADMSG" ;
3002
+ #endif
3003
+ case EBUSY :
3004
+ return "EBUSY" ;
3005
+ case ECHILD :
3006
+ return "ECHILD" ;
3007
+ #ifdef ECONNABORTED
3008
+ case ECONNABORTED :
3009
+ return "ECONNABORTED" ;
3010
+ #endif
3011
+ case ECONNREFUSED :
3012
+ return "ECONNREFUSED" ;
3013
+ #ifdef ECONNRESET
3014
+ case ECONNRESET :
3015
+ return "ECONNRESET" ;
3016
+ #endif
3017
+ case EDEADLK :
3018
+ return "EDEADLK" ;
3019
+ case EDOM :
3020
+ return "EDOM" ;
3021
+ case EEXIST :
3022
+ return "EEXIST" ;
3023
+ case EFAULT :
3024
+ return "EFAULT" ;
3025
+ case EFBIG :
3026
+ return "EFBIG" ;
3027
+ #ifdef EHOSTUNREACH
3028
+ case EHOSTUNREACH :
3029
+ return "EHOSTUNREACH" ;
3030
+ #endif
3031
+ case EIDRM :
3032
+ return "EIDRM" ;
3033
+ case EINPROGRESS :
3034
+ return "EINPROGRESS" ;
3035
+ case EINTR :
3036
+ return "EINTR" ;
3037
+ case EINVAL :
3038
+ return "EINVAL" ;
3039
+ case EIO :
3040
+ return "EIO" ;
3041
+ #ifdef EISCONN
3042
+ case EISCONN :
3043
+ return "EISCONN" ;
3044
+ #endif
3045
+ case EISDIR :
3046
+ return "EISDIR" ;
3047
+ #ifdef ELOOP
3048
+ case ELOOP :
3049
+ return "ELOOP" ;
3050
+ #endif
3051
+ case EMFILE :
3052
+ return "EMFILE" ;
3053
+ case EMLINK :
3054
+ return "EMLINK" ;
3055
+ case EMSGSIZE :
3056
+ return "EMSGSIZE" ;
3057
+ case ENAMETOOLONG :
3058
+ return "ENAMETOOLONG" ;
3059
+ case ENFILE :
3060
+ return "ENFILE" ;
3061
+ case ENOBUFS :
3062
+ return "ENOBUFS" ;
3063
+ case ENODEV :
3064
+ return "ENODEV" ;
3065
+ case ENOENT :
3066
+ return "ENOENT" ;
3067
+ case ENOEXEC :
3068
+ return "ENOEXEC" ;
3069
+ case ENOMEM :
3070
+ return "ENOMEM" ;
3071
+ case ENOSPC :
3072
+ return "ENOSPC" ;
3073
+ case ENOSYS :
3074
+ return "ENOSYS" ;
3075
+ #ifdef ENOTCONN
3076
+ case ENOTCONN :
3077
+ return "ENOTCONN" ;
3078
+ #endif
3079
+ case ENOTDIR :
3080
+ return "ENOTDIR" ;
3081
+ #if defined(ENOTEMPTY ) && (ENOTEMPTY != EEXIST ) /* same code on AIX */
3082
+ case ENOTEMPTY :
3083
+ return "ENOTEMPTY" ;
3084
+ #endif
3085
+ #ifdef ENOTSOCK
3086
+ case ENOTSOCK :
3087
+ return "ENOTSOCK" ;
3088
+ #endif
3089
+ #ifdef ENOTSUP
3090
+ case ENOTSUP :
3091
+ return "ENOTSUP" ;
3092
+ #endif
3093
+ case ENOTTY :
3094
+ return "ENOTTY" ;
3095
+ case ENXIO :
3096
+ return "ENXIO" ;
3097
+ #if defined(EOPNOTSUPP ) && (!defined(ENOTSUP ) || (EOPNOTSUPP != ENOTSUP ))
3098
+ case EOPNOTSUPP :
3099
+ return "EOPNOTSUPP" ;
3100
+ #endif
3101
+ #ifdef EOVERFLOW
3102
+ case EOVERFLOW :
3103
+ return "EOVERFLOW" ;
3104
+ #endif
3105
+ case EPERM :
3106
+ return "EPERM" ;
3107
+ case EPIPE :
3108
+ return "EPIPE" ;
3109
+ case EPROTONOSUPPORT :
3110
+ return "EPROTONOSUPPORT" ;
3111
+ case ERANGE :
3112
+ return "ERANGE" ;
3113
+ #ifdef EROFS
3114
+ case EROFS :
3115
+ return "EROFS" ;
3116
+ #endif
3117
+ case ESRCH :
3118
+ return "ESRCH" ;
3119
+ #ifdef ETIMEDOUT
3120
+ case ETIMEDOUT :
3121
+ return "ETIMEDOUT" ;
3122
+ #endif
3123
+ #ifdef ETXTBSY
3124
+ case ETXTBSY :
3125
+ return "ETXTBSY" ;
3126
+ #endif
3127
+ #if defined(EWOULDBLOCK ) && (!defined(EAGAIN ) || (EWOULDBLOCK != EAGAIN ))
3128
+ case EWOULDBLOCK :
3129
+ return "EWOULDBLOCK" ;
3130
+ #endif
3131
+ case EXDEV :
3132
+ return "EXDEV" ;
3133
+ }
3134
+
3135
+ return NULL ;
3136
+ }
3137
+
2959
3138
2960
3139
/*
2961
3140
* error_severity --- get localized string representing elevel
0 commit comments