@@ -153,6 +153,7 @@ static void send_message_to_server_log(ErrorData *edata);
153
153
static void send_message_to_frontend (ErrorData * edata );
154
154
static char * expand_fmt_string (const char * fmt , ErrorData * edata );
155
155
static const char * useful_strerror (int errnum );
156
+ static const char * get_errno_symbol (int errnum );
156
157
static const char * error_severity (int elevel );
157
158
static void append_with_tabs (StringInfo buf , const char * str );
158
159
static bool is_log_level_output (int elevel , int log_min_level );
@@ -2650,7 +2651,7 @@ expand_fmt_string(const char *fmt, ErrorData *edata)
2650
2651
static const char *
2651
2652
useful_strerror (int errnum )
2652
2653
{
2653
- /* this buffer is only used if errno has a bogus value */
2654
+ /* this buffer is only used if strerror() and get_errno_symbol() fail */
2654
2655
static char errorstr_buf [48 ];
2655
2656
const char * str ;
2656
2657
@@ -2662,10 +2663,16 @@ useful_strerror(int errnum)
2662
2663
str = strerror (errnum );
2663
2664
2664
2665
/*
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.
2667
2671
*/
2668
- if (str == NULL || * str == '\0' )
2672
+ if (str == NULL || * str == '\0' || * str == '?' )
2673
+ str = get_errno_symbol (errnum );
2674
+
2675
+ if (str == NULL )
2669
2676
{
2670
2677
snprintf (errorstr_buf , sizeof (errorstr_buf ),
2671
2678
/*------
@@ -2678,6 +2685,178 @@ useful_strerror(int errnum)
2678
2685
return str ;
2679
2686
}
2680
2687
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
+
2681
2860
2682
2861
/*
2683
2862
* error_severity --- get localized string representing elevel
0 commit comments