PostgreSQL Source Code git master
Loading...
Searching...
No Matches
strerror.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * strerror.c
4 * Replacements for standard strerror() and strerror_r() functions
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/port/strerror.c
12 *
13 *-------------------------------------------------------------------------
14 */
15#include "c.h"
16
17/*
18 * Within this file, "strerror" means the platform's function not pg_strerror,
19 * and likewise for "strerror_r"
20 */
21#undef strerror
22#undef strerror_r
23
24static char *gnuish_strerror_r(int errnum, char *buf, size_t buflen);
25static char *get_errno_symbol(int errnum);
26#ifdef WIN32
27static char *win32_socket_strerror(int errnum, char *buf, size_t buflen);
28#endif
29
30
31/*
32 * A slightly cleaned-up version of strerror()
33 */
34char *
41
42/*
43 * A slightly cleaned-up version of strerror_r()
44 */
45char *
46pg_strerror_r(int errnum, char *buf, size_t buflen)
47{
48 char *str;
49
50 /* If it's a Windows Winsock error, that needs special handling */
51#ifdef WIN32
52 /* Winsock error code range, per WinError.h */
53 if (errnum >= 10000 && errnum <= 11999)
54 return win32_socket_strerror(errnum, buf, buflen);
55#endif
56
57 /* Try the platform's strerror_r(), or maybe just strerror() */
58 str = gnuish_strerror_r(errnum, buf, buflen);
59
60 /*
61 * Some strerror()s return an empty string for out-of-range errno. This
62 * is ANSI C spec compliant, but not exactly useful. Also, we may get
63 * back strings of question marks if libc cannot transcode the message to
64 * the codeset specified by LC_CTYPE. If we get nothing useful, first try
65 * get_errno_symbol(), and if that fails, print the numeric errno.
66 */
67 if (str == NULL || *str == '\0' || *str == '?')
69
70 if (str == NULL)
71 {
72 snprintf(buf, buflen, _("operating system error %d"), errnum);
73 str = buf;
74 }
75
76 return str;
77}
78
79/*
80 * Simple wrapper to emulate GNU strerror_r if what the platform provides is
81 * POSIX. Also, if platform lacks strerror_r altogether, fall back to plain
82 * strerror; it might not be very thread-safe, but tough luck.
83 */
84static char *
85gnuish_strerror_r(int errnum, char *buf, size_t buflen)
86{
87#ifdef HAVE_STRERROR_R
88#ifdef STRERROR_R_INT
89 /* POSIX API */
90 if (strerror_r(errnum, buf, buflen) == 0)
91 return buf;
92 return NULL; /* let caller deal with failure */
93#else
94 /* GNU API */
95 return strerror_r(errnum, buf, buflen);
96#endif
97#else /* !HAVE_STRERROR_R */
98 char *sbuf = strerror(errnum);
99
100 if (sbuf == NULL) /* can this still happen anywhere? */
101 return NULL;
102 /* To minimize thread-unsafety hazard, copy into caller's buffer */
103 strlcpy(buf, sbuf, buflen);
104 return buf;
105#endif
106}
107
108/*
109 * Returns a symbol (e.g. "ENOENT") for an errno code.
110 * Returns NULL if the code is unrecognized.
111 */
112static char *
114{
115 switch (errnum)
116 {
117 case E2BIG:
118 return "E2BIG";
119 case EACCES:
120 return "EACCES";
121 case EADDRINUSE:
122 return "EADDRINUSE";
123 case EADDRNOTAVAIL:
124 return "EADDRNOTAVAIL";
125 case EAFNOSUPPORT:
126 return "EAFNOSUPPORT";
127#ifdef EAGAIN
128 case EAGAIN:
129 return "EAGAIN";
130#endif
131#ifdef EALREADY
132 case EALREADY:
133 return "EALREADY";
134#endif
135 case EBADF:
136 return "EBADF";
137#ifdef EBADMSG
138 case EBADMSG:
139 return "EBADMSG";
140#endif
141 case EBUSY:
142 return "EBUSY";
143 case ECHILD:
144 return "ECHILD";
145 case ECONNABORTED:
146 return "ECONNABORTED";
147 case ECONNREFUSED:
148 return "ECONNREFUSED";
149 case ECONNRESET:
150 return "ECONNRESET";
151 case EDEADLK:
152 return "EDEADLK";
153 case EDOM:
154 return "EDOM";
155 case EEXIST:
156 return "EEXIST";
157 case EFAULT:
158 return "EFAULT";
159 case EFBIG:
160 return "EFBIG";
161 case EHOSTDOWN:
162 return "EHOSTDOWN";
163 case EHOSTUNREACH:
164 return "EHOSTUNREACH";
165 case EIDRM:
166 return "EIDRM";
167 case EINPROGRESS:
168 return "EINPROGRESS";
169 case EINTR:
170 return "EINTR";
171 case EINVAL:
172 return "EINVAL";
173 case EIO:
174 return "EIO";
175 case EISCONN:
176 return "EISCONN";
177 case EISDIR:
178 return "EISDIR";
179#ifdef ELOOP
180 case ELOOP:
181 return "ELOOP";
182#endif
183 case EMFILE:
184 return "EMFILE";
185 case EMLINK:
186 return "EMLINK";
187 case EMSGSIZE:
188 return "EMSGSIZE";
189 case ENAMETOOLONG:
190 return "ENAMETOOLONG";
191 case ENETDOWN:
192 return "ENETDOWN";
193 case ENETRESET:
194 return "ENETRESET";
195 case ENETUNREACH:
196 return "ENETUNREACH";
197 case ENFILE:
198 return "ENFILE";
199 case ENOBUFS:
200 return "ENOBUFS";
201 case ENODEV:
202 return "ENODEV";
203 case ENOENT:
204 return "ENOENT";
205 case ENOEXEC:
206 return "ENOEXEC";
207 case ENOMEM:
208 return "ENOMEM";
209 case ENOSPC:
210 return "ENOSPC";
211 case ENOSYS:
212 return "ENOSYS";
213 case ENOTCONN:
214 return "ENOTCONN";
215 case ENOTDIR:
216 return "ENOTDIR";
217#if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST) /* same code on AIX */
218 case ENOTEMPTY:
219 return "ENOTEMPTY";
220#endif
221 case ENOTSOCK:
222 return "ENOTSOCK";
223#ifdef ENOTSUP
224 case ENOTSUP:
225 return "ENOTSUP";
226#endif
227 case ENOTTY:
228 return "ENOTTY";
229 case ENXIO:
230 return "ENXIO";
231#if defined(EOPNOTSUPP) && (!defined(ENOTSUP) || (EOPNOTSUPP != ENOTSUP))
232 case EOPNOTSUPP:
233 return "EOPNOTSUPP";
234#endif
235#ifdef EOVERFLOW
236 case EOVERFLOW:
237 return "EOVERFLOW";
238#endif
239 case EPERM:
240 return "EPERM";
241 case EPIPE:
242 return "EPIPE";
243 case EPROTONOSUPPORT:
244 return "EPROTONOSUPPORT";
245 case ERANGE:
246 return "ERANGE";
247#ifdef EROFS
248 case EROFS:
249 return "EROFS";
250#endif
251 case ESRCH:
252 return "ESRCH";
253 case ETIMEDOUT:
254 return "ETIMEDOUT";
255#ifdef ETXTBSY
256 case ETXTBSY:
257 return "ETXTBSY";
258#endif
259#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
260 case EWOULDBLOCK:
261 return "EWOULDBLOCK";
262#endif
263 case EXDEV:
264 return "EXDEV";
265 }
266
267 return NULL;
268}
269
270
271#ifdef WIN32
272
273/*
274 * Windows' strerror() doesn't know the Winsock codes, so handle them this way
275 */
276static char *
277win32_socket_strerror(int errnum, char *buf, size_t buflen)
278{
280
282 {
283 handleDLL = LoadLibraryEx("netmsg.dll", NULL,
285 if (handleDLL == NULL)
286 {
287 snprintf(buf, buflen,
288 "winsock error %d (could not load netmsg.dll to translate: error code %lu)",
290 return buf;
291 }
292 }
293
294 ZeroMemory(buf, buflen);
298 handleDLL,
299 errnum,
301 buf,
302 buflen - 1,
303 NULL) == 0)
304 {
305 /* Failed to get id */
306 snprintf(buf, buflen, "unrecognized winsock error %d", errnum);
307 }
308
309 return buf;
310}
311
312#endif /* WIN32 */
#define _(x)
Definition elog.c:95
const char * str
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define PG_STRERROR_R_BUFLEN
Definition port.h:278
#define strerror
Definition port.h:273
#define snprintf
Definition port.h:260
#define strerror_r
Definition port.h:277
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
static int fb(int x)
#define EOVERFLOW
Definition private.h:41
#define ENOTSUP
Definition private.h:38
static char * get_errno_symbol(int errnum)
Definition strerror.c:113
char * pg_strerror_r(int errnum, char *buf, size_t buflen)
Definition strerror.c:46
static char * gnuish_strerror_r(int errnum, char *buf, size_t buflen)
Definition strerror.c:85
char * pg_strerror(int errnum)
Definition strerror.c:35
#define EISCONN
Definition win32_port.h:375
#define ENETUNREACH
Definition win32_port.h:399
#define ECONNABORTED
Definition win32_port.h:369
#define EINTR
Definition win32_port.h:361
#define EWOULDBLOCK
Definition win32_port.h:367
#define EOPNOTSUPP
Definition win32_port.h:385
#define EAFNOSUPPORT
Definition win32_port.h:365
#define EHOSTUNREACH
Definition win32_port.h:393
#define EADDRNOTAVAIL
Definition win32_port.h:389
#define ETIMEDOUT
Definition win32_port.h:403
#define EADDRINUSE
Definition win32_port.h:387
#define EINPROGRESS
Definition win32_port.h:373
#define ENETRESET
Definition win32_port.h:397
#define ENOBUFS
Definition win32_port.h:377
#define EHOSTDOWN
Definition win32_port.h:391
#define ENETDOWN
Definition win32_port.h:395
#define ECONNREFUSED
Definition win32_port.h:381
#define EPROTONOSUPPORT
Definition win32_port.h:379
#define EIDRM
Definition win32_port.h:102
#define ECONNRESET
Definition win32_port.h:371
#define ENOTSOCK
Definition win32_port.h:383
#define EMSGSIZE
Definition win32_port.h:363
#define EAGAIN
Definition win32_port.h:359
#define ENOTCONN
Definition win32_port.h:401