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