@@ -170,6 +170,7 @@ static void send_message_to_server_log(ErrorData *edata);
170
170
static void send_message_to_frontend (ErrorData * edata );
171
171
static char * expand_fmt_string (const char * fmt , ErrorData * edata );
172
172
static const char * useful_strerror (int errnum );
173
+ static const char * get_errno_symbol (int errnum );
173
174
static const char * error_severity (int elevel );
174
175
static void append_with_tabs (StringInfo buf , const char * str );
175
176
static bool is_log_level_output (int elevel , int log_min_level );
@@ -2784,7 +2785,7 @@ expand_fmt_string(const char *fmt, ErrorData *edata)
2784
2785
static const char *
2785
2786
useful_strerror (int errnum )
2786
2787
{
2787
- /* this buffer is only used if errno has a bogus value */
2788
+ /* this buffer is only used if strerror() and get_errno_symbol() fail */
2788
2789
static char errorstr_buf [48 ];
2789
2790
const char * str ;
2790
2791
@@ -2796,10 +2797,16 @@ useful_strerror(int errnum)
2796
2797
str = strerror (errnum );
2797
2798
2798
2799
/*
2799
- * Some strerror()s return an empty string for out-of-range errno. This is
2800
- * ANSI C spec compliant, but not exactly useful.
2800
+ * Some strerror()s return an empty string for out-of-range errno. This
2801
+ * is ANSI C spec compliant, but not exactly useful. Also, we may get
2802
+ * back strings of question marks if libc cannot transcode the message to
2803
+ * the codeset specified by LC_CTYPE. If we get nothing useful, first try
2804
+ * get_errno_symbol(), and if that fails, print the numeric errno.
2801
2805
*/
2802
- if (str == NULL || * str == '\0' )
2806
+ if (str == NULL || * str == '\0' || * str == '?' )
2807
+ str = get_errno_symbol (errnum );
2808
+
2809
+ if (str == NULL )
2803
2810
{
2804
2811
snprintf (errorstr_buf , sizeof (errorstr_buf ),
2805
2812
/*------
@@ -2812,6 +2819,178 @@ useful_strerror(int errnum)
2812
2819
return str ;
2813
2820
}
2814
2821
2822
+ /*
2823
+ * Returns a symbol (e.g. "ENOENT") for an errno code.
2824
+ * Returns NULL if the code is unrecognized.
2825
+ */
2826
+ static const char *
2827
+ get_errno_symbol (int errnum )
2828
+ {
2829
+ switch (errnum )
2830
+ {
2831
+ case E2BIG :
2832
+ return "E2BIG" ;
2833
+ case EACCES :
2834
+ return "EACCES" ;
2835
+ #ifdef EADDRINUSE
2836
+ case EADDRINUSE :
2837
+ return "EADDRINUSE" ;
2838
+ #endif
2839
+ #ifdef EADDRNOTAVAIL
2840
+ case EADDRNOTAVAIL :
2841
+ return "EADDRNOTAVAIL" ;
2842
+ #endif
2843
+ case EAFNOSUPPORT :
2844
+ return "EAFNOSUPPORT" ;
2845
+ #ifdef EAGAIN
2846
+ case EAGAIN :
2847
+ return "EAGAIN" ;
2848
+ #endif
2849
+ #ifdef EALREADY
2850
+ case EALREADY :
2851
+ return "EALREADY" ;
2852
+ #endif
2853
+ case EBADF :
2854
+ return "EBADF" ;
2855
+ #ifdef EBADMSG
2856
+ case EBADMSG :
2857
+ return "EBADMSG" ;
2858
+ #endif
2859
+ case EBUSY :
2860
+ return "EBUSY" ;
2861
+ case ECHILD :
2862
+ return "ECHILD" ;
2863
+ #ifdef ECONNABORTED
2864
+ case ECONNABORTED :
2865
+ return "ECONNABORTED" ;
2866
+ #endif
2867
+ case ECONNREFUSED :
2868
+ return "ECONNREFUSED" ;
2869
+ #ifdef ECONNRESET
2870
+ case ECONNRESET :
2871
+ return "ECONNRESET" ;
2872
+ #endif
2873
+ case EDEADLK :
2874
+ return "EDEADLK" ;
2875
+ case EDOM :
2876
+ return "EDOM" ;
2877
+ case EEXIST :
2878
+ return "EEXIST" ;
2879
+ case EFAULT :
2880
+ return "EFAULT" ;
2881
+ case EFBIG :
2882
+ return "EFBIG" ;
2883
+ #ifdef EHOSTUNREACH
2884
+ case EHOSTUNREACH :
2885
+ return "EHOSTUNREACH" ;
2886
+ #endif
2887
+ case EIDRM :
2888
+ return "EIDRM" ;
2889
+ case EINPROGRESS :
2890
+ return "EINPROGRESS" ;
2891
+ case EINTR :
2892
+ return "EINTR" ;
2893
+ case EINVAL :
2894
+ return "EINVAL" ;
2895
+ case EIO :
2896
+ return "EIO" ;
2897
+ #ifdef EISCONN
2898
+ case EISCONN :
2899
+ return "EISCONN" ;
2900
+ #endif
2901
+ case EISDIR :
2902
+ return "EISDIR" ;
2903
+ #ifdef ELOOP
2904
+ case ELOOP :
2905
+ return "ELOOP" ;
2906
+ #endif
2907
+ case EMFILE :
2908
+ return "EMFILE" ;
2909
+ case EMLINK :
2910
+ return "EMLINK" ;
2911
+ case EMSGSIZE :
2912
+ return "EMSGSIZE" ;
2913
+ case ENAMETOOLONG :
2914
+ return "ENAMETOOLONG" ;
2915
+ case ENFILE :
2916
+ return "ENFILE" ;
2917
+ case ENOBUFS :
2918
+ return "ENOBUFS" ;
2919
+ case ENODEV :
2920
+ return "ENODEV" ;
2921
+ case ENOENT :
2922
+ return "ENOENT" ;
2923
+ case ENOEXEC :
2924
+ return "ENOEXEC" ;
2925
+ case ENOMEM :
2926
+ return "ENOMEM" ;
2927
+ case ENOSPC :
2928
+ return "ENOSPC" ;
2929
+ case ENOSYS :
2930
+ return "ENOSYS" ;
2931
+ #ifdef ENOTCONN
2932
+ case ENOTCONN :
2933
+ return "ENOTCONN" ;
2934
+ #endif
2935
+ case ENOTDIR :
2936
+ return "ENOTDIR" ;
2937
+ #if defined(ENOTEMPTY ) && (ENOTEMPTY != EEXIST ) /* same code on AIX */
2938
+ case ENOTEMPTY :
2939
+ return "ENOTEMPTY" ;
2940
+ #endif
2941
+ #ifdef ENOTSOCK
2942
+ case ENOTSOCK :
2943
+ return "ENOTSOCK" ;
2944
+ #endif
2945
+ #ifdef ENOTSUP
2946
+ case ENOTSUP :
2947
+ return "ENOTSUP" ;
2948
+ #endif
2949
+ case ENOTTY :
2950
+ return "ENOTTY" ;
2951
+ case ENXIO :
2952
+ return "ENXIO" ;
2953
+ #if defined(EOPNOTSUPP ) && (!defined(ENOTSUP ) || (EOPNOTSUPP != ENOTSUP ))
2954
+ case EOPNOTSUPP :
2955
+ return "EOPNOTSUPP" ;
2956
+ #endif
2957
+ #ifdef EOVERFLOW
2958
+ case EOVERFLOW :
2959
+ return "EOVERFLOW" ;
2960
+ #endif
2961
+ case EPERM :
2962
+ return "EPERM" ;
2963
+ case EPIPE :
2964
+ return "EPIPE" ;
2965
+ case EPROTONOSUPPORT :
2966
+ return "EPROTONOSUPPORT" ;
2967
+ case ERANGE :
2968
+ return "ERANGE" ;
2969
+ #ifdef EROFS
2970
+ case EROFS :
2971
+ return "EROFS" ;
2972
+ #endif
2973
+ case ESRCH :
2974
+ return "ESRCH" ;
2975
+ #ifdef ETIMEDOUT
2976
+ case ETIMEDOUT :
2977
+ return "ETIMEDOUT" ;
2978
+ #endif
2979
+ #ifdef ETXTBSY
2980
+ case ETXTBSY :
2981
+ return "ETXTBSY" ;
2982
+ #endif
2983
+ #if defined(EWOULDBLOCK ) && (!defined(EAGAIN ) || (EWOULDBLOCK != EAGAIN ))
2984
+ case EWOULDBLOCK :
2985
+ return "EWOULDBLOCK" ;
2986
+ #endif
2987
+ case EXDEV :
2988
+ return "EXDEV" ;
2989
+ }
2990
+
2991
+ return NULL ;
2992
+ }
2993
+
2815
2994
2816
2995
/*
2817
2996
* error_severity --- get localized string representing elevel
0 commit comments