/src/httpd/srclib/apr/misc/unix/errorcodes.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Licensed to the Apache Software Foundation (ASF) under one or more |
2 | | * contributor license agreements. See the NOTICE file distributed with |
3 | | * this work for additional information regarding copyright ownership. |
4 | | * The ASF licenses this file to You under the Apache License, Version 2.0 |
5 | | * (the "License"); you may not use this file except in compliance with |
6 | | * the License. You may obtain a copy of the License at |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | |
17 | | #include "apr_arch_misc.h" |
18 | | #include "apr_strings.h" |
19 | | #include "apr_lib.h" |
20 | | #include "apr_dso.h" |
21 | | |
22 | | #include "apu_errno.h" |
23 | | |
24 | | #if APR_HAVE_NETDB_H |
25 | | #include <netdb.h> |
26 | | #endif |
27 | | #ifdef HAVE_DLFCN_H |
28 | | #include <dlfcn.h> |
29 | | #endif |
30 | | |
31 | | /* |
32 | | * stuffbuffer - like apr_cpystrn() but returns the address of the |
33 | | * dest buffer instead of the address of the terminating '\0' |
34 | | */ |
35 | | static char *stuffbuffer(char *buf, apr_size_t bufsize, const char *s) |
36 | 0 | { |
37 | 0 | apr_cpystrn(buf,s,bufsize); |
38 | 0 | return buf; |
39 | 0 | } |
40 | | |
41 | | static char *apr_error_string(apr_status_t statcode) |
42 | 0 | { |
43 | 0 | switch (statcode) { |
44 | 0 | case APR_ENOSTAT: |
45 | 0 | return "Could not perform a stat on the file."; |
46 | 0 | case APR_ENOPOOL: |
47 | 0 | return "A new pool could not be created."; |
48 | 0 | case APR_EBADDATE: |
49 | 0 | return "An invalid date has been provided"; |
50 | 0 | case APR_EINVALSOCK: |
51 | 0 | return "An invalid socket was returned"; |
52 | 0 | case APR_ENOPROC: |
53 | 0 | return "No process was provided and one was required."; |
54 | 0 | case APR_ENOTIME: |
55 | 0 | return "No time was provided and one was required."; |
56 | 0 | case APR_ENODIR: |
57 | 0 | return "No directory was provided and one was required."; |
58 | 0 | case APR_ENOLOCK: |
59 | 0 | return "No lock was provided and one was required."; |
60 | 0 | case APR_ENOPOLL: |
61 | 0 | return "No poll structure was provided and one was required."; |
62 | 0 | case APR_ENOSOCKET: |
63 | 0 | return "No socket was provided and one was required."; |
64 | 0 | case APR_ENOTHREAD: |
65 | 0 | return "No thread was provided and one was required."; |
66 | 0 | case APR_ENOTHDKEY: |
67 | 0 | return "No thread key structure was provided and one was required."; |
68 | 0 | case APR_ENOSHMAVAIL: |
69 | 0 | return "No shared memory is currently available"; |
70 | 0 | case APR_EDSOOPEN: |
71 | | #if APR_HAS_DSO && defined(HAVE_LIBDL) |
72 | | return dlerror(); |
73 | | #else |
74 | 0 | return "DSO load failed"; |
75 | 0 | #endif /* HAVE_LIBDL */ |
76 | 0 | case APR_EBADIP: |
77 | 0 | return "The specified IP address is invalid."; |
78 | 0 | case APR_EBADMASK: |
79 | 0 | return "The specified network mask is invalid."; |
80 | 0 | case APR_ESYMNOTFOUND: |
81 | 0 | return "Could not find the requested symbol."; |
82 | 0 | case APR_ENOTENOUGHENTROPY: |
83 | 0 | return "Not enough entropy to continue."; |
84 | 0 | case APR_INCHILD: |
85 | 0 | return |
86 | 0 | "Your code just forked, and you are currently executing in the " |
87 | 0 | "child process"; |
88 | 0 | case APR_INPARENT: |
89 | 0 | return |
90 | 0 | "Your code just forked, and you are currently executing in the " |
91 | 0 | "parent process"; |
92 | 0 | case APR_DETACH: |
93 | 0 | return "The specified thread is detached"; |
94 | 0 | case APR_NOTDETACH: |
95 | 0 | return "The specified thread is not detached"; |
96 | 0 | case APR_CHILD_DONE: |
97 | 0 | return "The specified child process is done executing"; |
98 | 0 | case APR_CHILD_NOTDONE: |
99 | 0 | return "The specified child process is not done executing"; |
100 | 0 | case APR_TIMEUP: |
101 | 0 | return "The timeout specified has expired"; |
102 | 0 | case APR_INCOMPLETE: |
103 | 0 | return "Partial results are valid but processing is incomplete"; |
104 | 0 | case APR_BADCH: |
105 | 0 | return "Bad character specified on command line"; |
106 | 0 | case APR_BADARG: |
107 | 0 | return "Missing parameter for the specified command line option"; |
108 | 0 | case APR_EOF: |
109 | 0 | return "End of file found"; |
110 | 0 | case APR_NOTFOUND: |
111 | 0 | return "Could not find specified socket in poll list."; |
112 | 0 | case APR_ANONYMOUS: |
113 | 0 | return "Shared memory is implemented anonymously"; |
114 | 0 | case APR_FILEBASED: |
115 | 0 | return "Shared memory is implemented using files"; |
116 | 0 | case APR_KEYBASED: |
117 | 0 | return "Shared memory is implemented using a key system"; |
118 | 0 | case APR_EINIT: |
119 | 0 | return |
120 | 0 | "There is no error, this value signifies an initialized " |
121 | 0 | "error code"; |
122 | 0 | case APR_ENOTIMPL: |
123 | 0 | return "This function has not been implemented on this platform"; |
124 | 0 | case APR_EMISMATCH: |
125 | 0 | return "passwords do not match"; |
126 | 0 | case APR_EABSOLUTE: |
127 | 0 | return "The given path is absolute"; |
128 | 0 | case APR_ERELATIVE: |
129 | 0 | return "The given path is relative"; |
130 | 0 | case APR_EINCOMPLETE: |
131 | 0 | return "The given path is incomplete"; |
132 | 0 | case APR_EABOVEROOT: |
133 | 0 | return "The given path was above the root path"; |
134 | 0 | case APR_EBADPATH: |
135 | 0 | return "The given path is misformatted or contained invalid characters"; |
136 | 0 | case APR_EPATHWILD: |
137 | 0 | return "The given path contained wildcard characters"; |
138 | 0 | case APR_EBUSY: |
139 | 0 | return "The given lock was busy."; |
140 | 0 | case APR_EPROC_UNKNOWN: |
141 | 0 | return "The process is not recognized."; |
142 | 0 | case APR_EALREADY: |
143 | 0 | return "Operation already in progress"; |
144 | 0 | case APR_EGENERAL: |
145 | 0 | return "Internal error (specific information not available)"; |
146 | | |
147 | | /* APR Util error codes */ |
148 | | |
149 | 0 | case APR_ENOKEY: |
150 | 0 | return "The key provided was empty or NULL"; |
151 | 0 | case APR_ENOIV: |
152 | 0 | return "The initialisation vector provided was NULL"; |
153 | 0 | case APR_EKEYTYPE: |
154 | 0 | return "The key type was not recognised"; |
155 | 0 | case APR_ENOSPACE: |
156 | 0 | return "The buffer supplied was not big enough"; |
157 | 0 | case APR_ECRYPT: |
158 | 0 | return "Internal error in the crypto subsystem (specific information not available)"; |
159 | 0 | case APR_EPADDING: |
160 | 0 | return "Padding was not supported"; |
161 | 0 | case APR_EKEYLENGTH: |
162 | 0 | return "The key length was incorrect"; |
163 | 0 | case APR_ENOCIPHER: |
164 | 0 | return "The cipher provided was not recognised"; |
165 | 0 | case APR_ENODIGEST: |
166 | 0 | return "The digest provided was not recognised"; |
167 | 0 | case APR_ENOENGINE: |
168 | 0 | return "No engine found for crypto subsystem"; |
169 | 0 | case APR_EINITENGINE: |
170 | 0 | return "Failed to init engine for crypto subsystem"; |
171 | 0 | case APR_EREINIT: |
172 | 0 | return "Underlying crypto has already been initialised"; |
173 | 0 | case APR_ENOVERIFY: |
174 | 0 | return "The signature verification failed"; |
175 | | |
176 | 0 | case APR_WANT_READ: |
177 | 0 | return "Call me again when the socket is ready for reading"; |
178 | 0 | case APR_WANT_WRITE: |
179 | 0 | return "Call me again when the socket is ready for writing"; |
180 | | |
181 | 0 | case APR_OTHER: |
182 | 0 | return "An internal LDAP error has occurred"; |
183 | 0 | case APR_SERVER_DOWN: |
184 | 0 | return "The server is down"; |
185 | 0 | case APR_LOCAL_ERROR: |
186 | 0 | return "An error has occurred locally"; |
187 | 0 | case APR_ENCODING_ERROR: |
188 | 0 | return "Encoding has failed"; |
189 | 0 | case APR_DECODING_ERROR: |
190 | 0 | return "Decoding has failed"; |
191 | 0 | case APR_AUTH_UNKNOWN: |
192 | 0 | return "Unknown SASL mechanism"; |
193 | 0 | case APR_FILTER_ERROR: |
194 | 0 | return "The filter was malformed"; |
195 | 0 | case APR_USER_CANCELLED: |
196 | 0 | return "User has cancelled the request"; |
197 | 0 | case APR_PARAM_ERROR: |
198 | 0 | return "Parameter error"; |
199 | 0 | case APR_CONNECT_ERROR: |
200 | 0 | return "Connect error"; |
201 | 0 | case APR_NOT_SUPPORTED: |
202 | 0 | return "Not supported"; |
203 | 0 | case APR_CONTROL_NOT_FOUND: |
204 | 0 | return "Control not found"; |
205 | 0 | case APR_NO_RESULTS_RETURNED: |
206 | 0 | return "No results returned"; |
207 | 0 | case APR_MORE_RESULTS_TO_RETURN: |
208 | 0 | return "More results to be returned"; |
209 | 0 | case APR_CLIENT_LOOP: |
210 | 0 | return "Client loop has occurred"; |
211 | 0 | case APR_REFERRAL_LIMIT_EXCEEDED: |
212 | 0 | return "Referral limit exceeded"; |
213 | 0 | case APR_CONNECTING: |
214 | 0 | return "Connecting"; |
215 | | |
216 | 0 | case APR_OPERATIONS_ERROR: |
217 | 0 | return "Operations error has occurred"; |
218 | 0 | case APR_PROTOCOL_ERROR: |
219 | 0 | return "Protocol error has occurred"; |
220 | 0 | case APR_TIMELIMIT_EXCEEDED: |
221 | 0 | return "Time limit has been exceeded"; |
222 | 0 | case APR_SIZELIMIT_EXCEEDED: |
223 | 0 | return "Size limit has been exceeded"; |
224 | 0 | case APR_PROXY_AUTH: |
225 | 0 | return "Proxy authorization has failed"; |
226 | 0 | case APR_INAPPROPRIATE_AUTH: |
227 | 0 | return "Authentication not appropriate for this entry"; |
228 | 0 | case APR_INVALID_CREDENTIALS: |
229 | 0 | return "Invalid credentials were presented"; |
230 | 0 | case APR_INSUFFICIENT_ACCESS: |
231 | 0 | return "The user has insufficient access"; |
232 | 0 | case APR_UNAVAILABLE: |
233 | 0 | return "Unavailable"; |
234 | 0 | case APR_CONSTRAINT_VIOLATION: |
235 | 0 | return "A constraint was violated"; |
236 | 0 | case APR_NO_SUCH_OBJECT: |
237 | 0 | return "No such object"; |
238 | 0 | case APR_NO_SUCH_ATTRIBUTE: |
239 | 0 | return "No such attribute"; |
240 | 0 | case APR_COMPARE_TRUE: |
241 | 0 | return "Comparison is true"; |
242 | 0 | case APR_COMPARE_FALSE: |
243 | 0 | return "Comparison is false"; |
244 | 0 | case APR_ALREADY_EXISTS: |
245 | 0 | return "The object already exists"; |
246 | 0 | case APR_OBJECT_CLASS_VIOLATION: |
247 | 0 | return "Add or modify results in an objectclass violation"; |
248 | | |
249 | 0 | default: |
250 | 0 | return "Error string not specified yet"; |
251 | 0 | } |
252 | 0 | } |
253 | | |
254 | | |
255 | | #ifdef OS2 |
256 | | #include <ctype.h> |
257 | | |
258 | | int apr_canonical_error(apr_status_t err); |
259 | | |
260 | | static char *apr_os_strerror(char* buf, apr_size_t bufsize, int err) |
261 | | { |
262 | | char result[200]; |
263 | | unsigned char message[HUGE_STRING_LEN]; |
264 | | ULONG len; |
265 | | char *pos; |
266 | | int c; |
267 | | |
268 | | if (err >= 10000 && err < 12000) { /* socket error codes */ |
269 | | return stuffbuffer(buf, bufsize, |
270 | | strerror(apr_canonical_error(err+APR_OS_START_SYSERR))); |
271 | | } |
272 | | else if (DosGetMessage(NULL, 0, message, HUGE_STRING_LEN, err, |
273 | | "OSO001.MSG", &len) == 0) { |
274 | | len--; |
275 | | message[len] = 0; |
276 | | pos = result; |
277 | | |
278 | | if (len >= sizeof(result)) |
279 | | len = sizeof(result) - 1; |
280 | | |
281 | | for (c=0; c<len; c++) { |
282 | | /* skip multiple whitespace */ |
283 | | while (apr_isspace(message[c]) && apr_isspace(message[c+1])) |
284 | | c++; |
285 | | *(pos++) = apr_isspace(message[c]) ? ' ' : message[c]; |
286 | | } |
287 | | |
288 | | *pos = 0; |
289 | | } |
290 | | else { |
291 | | sprintf(result, "OS/2 error %d", err); |
292 | | } |
293 | | |
294 | | /* Stuff the string into the caller supplied buffer, then return |
295 | | * a pointer to it. |
296 | | */ |
297 | | return stuffbuffer(buf, bufsize, result); |
298 | | } |
299 | | |
300 | | #elif defined(WIN32) || (defined(NETWARE) && defined(USE_WINSOCK)) |
301 | | |
302 | | static const struct { |
303 | | apr_status_t code; |
304 | | const char *msg; |
305 | | } gaErrorList[] = { |
306 | | {WSAEINTR, "Interrupted system call"}, |
307 | | {WSAEBADF, "Bad file number"}, |
308 | | {WSAEACCES, "Permission denied"}, |
309 | | {WSAEFAULT, "Bad address"}, |
310 | | {WSAEINVAL, "Invalid argument"}, |
311 | | {WSAEMFILE, "Too many open sockets"}, |
312 | | {WSAEWOULDBLOCK, "Operation would block"}, |
313 | | {WSAEINPROGRESS, "Operation now in progress"}, |
314 | | {WSAEALREADY, "Operation already in progress"}, |
315 | | {WSAENOTSOCK, "Socket operation on non-socket"}, |
316 | | {WSAEDESTADDRREQ, "Destination address required"}, |
317 | | {WSAEMSGSIZE, "Message too long"}, |
318 | | {WSAEPROTOTYPE, "Protocol wrong type for socket"}, |
319 | | {WSAENOPROTOOPT, "Bad protocol option"}, |
320 | | {WSAEPROTONOSUPPORT, "Protocol not supported"}, |
321 | | {WSAESOCKTNOSUPPORT, "Socket type not supported"}, |
322 | | {WSAEOPNOTSUPP, "Operation not supported on socket"}, |
323 | | {WSAEPFNOSUPPORT, "Protocol family not supported"}, |
324 | | {WSAEAFNOSUPPORT, "Address family not supported"}, |
325 | | {WSAEADDRINUSE, "Address already in use"}, |
326 | | {WSAEADDRNOTAVAIL, "Can't assign requested address"}, |
327 | | {WSAENETDOWN, "Network is down"}, |
328 | | {WSAENETUNREACH, "Network is unreachable"}, |
329 | | {WSAENETRESET, "Net connection reset"}, |
330 | | {WSAECONNABORTED, "Software caused connection abort"}, |
331 | | {WSAECONNRESET, "Connection reset by peer"}, |
332 | | {WSAENOBUFS, "No buffer space available"}, |
333 | | {WSAEISCONN, "Socket is already connected"}, |
334 | | {WSAENOTCONN, "Socket is not connected"}, |
335 | | {WSAESHUTDOWN, "Can't send after socket shutdown"}, |
336 | | {WSAETOOMANYREFS, "Too many references, can't splice"}, |
337 | | {WSAETIMEDOUT, "Connection timed out"}, |
338 | | {WSAECONNREFUSED, "Connection refused"}, |
339 | | {WSAELOOP, "Too many levels of symbolic links"}, |
340 | | {WSAENAMETOOLONG, "File name too long"}, |
341 | | {WSAEHOSTDOWN, "Host is down"}, |
342 | | {WSAEHOSTUNREACH, "No route to host"}, |
343 | | {WSAENOTEMPTY, "Directory not empty"}, |
344 | | {WSAEPROCLIM, "Too many processes"}, |
345 | | {WSAEUSERS, "Too many users"}, |
346 | | {WSAEDQUOT, "Disc quota exceeded"}, |
347 | | {WSAESTALE, "Stale NFS file handle"}, |
348 | | {WSAEREMOTE, "Too many levels of remote in path"}, |
349 | | {WSASYSNOTREADY, "Network system is unavailable"}, |
350 | | {WSAVERNOTSUPPORTED, "Winsock version out of range"}, |
351 | | {WSANOTINITIALISED, "WSAStartup not yet called"}, |
352 | | {WSAEDISCON, "Graceful shutdown in progress"}, |
353 | | {WSAHOST_NOT_FOUND, "Host not found"}, |
354 | | {WSANO_DATA, "No host data of that type was found"}, |
355 | | {0, NULL} |
356 | | }; |
357 | | |
358 | | |
359 | | static char *apr_os_strerror(char *buf, apr_size_t bufsize, apr_status_t errcode) |
360 | | { |
361 | | apr_size_t len=0, i; |
362 | | |
363 | | #ifndef NETWARE |
364 | | len = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
365 | | | FORMAT_MESSAGE_IGNORE_INSERTS, |
366 | | NULL, |
367 | | errcode, |
368 | | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ |
369 | | buf, |
370 | | (DWORD)bufsize, |
371 | | NULL); |
372 | | #endif |
373 | | |
374 | | if (!len) { |
375 | | for (i = 0; gaErrorList[i].msg; ++i) { |
376 | | if (gaErrorList[i].code == errcode) { |
377 | | apr_cpystrn(buf, gaErrorList[i].msg, bufsize); |
378 | | len = strlen(buf); |
379 | | break; |
380 | | } |
381 | | } |
382 | | } |
383 | | |
384 | | if (len) { |
385 | | /* FormatMessage put the message in the buffer, but it may |
386 | | * have embedded a newline (\r\n), and possible more than one. |
387 | | * Remove the newlines replacing them with a space. This is not |
388 | | * as visually perfect as moving all the remaining message over, |
389 | | * but more efficient. |
390 | | */ |
391 | | i = len; |
392 | | while (i) { |
393 | | i--; |
394 | | if ((buf[i] == '\r') || (buf[i] == '\n')) |
395 | | buf[i] = ' '; |
396 | | } |
397 | | } |
398 | | else { |
399 | | /* Windows didn't provide us with a message. Even stuff like * WSAECONNREFUSED won't get a message. |
400 | | */ |
401 | | apr_snprintf(buf, bufsize, "Unrecognized Win32 error code %d", errcode); |
402 | | } |
403 | | |
404 | | return buf; |
405 | | } |
406 | | |
407 | | #else |
408 | | /* On Unix, apr_os_strerror() handles error codes from the resolver |
409 | | * (h_errno). |
410 | | */ |
411 | | static char *apr_os_strerror(char* buf, apr_size_t bufsize, int err) |
412 | 0 | { |
413 | | #ifdef HAVE_HSTRERROR |
414 | | return stuffbuffer(buf, bufsize, hstrerror(err)); |
415 | | #else /* HAVE_HSTRERROR */ |
416 | 0 | const char *msg; |
417 | |
|
418 | 0 | switch(err) { |
419 | 0 | case HOST_NOT_FOUND: |
420 | 0 | msg = "Unknown host"; |
421 | 0 | break; |
422 | 0 | #if defined(NO_DATA) |
423 | 0 | case NO_DATA: |
424 | | #if defined(NO_ADDRESS) && (NO_DATA != NO_ADDRESS) |
425 | | case NO_ADDRESS: |
426 | | #endif |
427 | 0 | msg = "No address for host"; |
428 | 0 | break; |
429 | | #elif defined(NO_ADDRESS) |
430 | | case NO_ADDRESS: |
431 | | msg = "No address for host"; |
432 | | break; |
433 | | #endif /* NO_DATA */ |
434 | 0 | default: |
435 | 0 | msg = "Unrecognized resolver error"; |
436 | 0 | } |
437 | 0 | return stuffbuffer(buf, bufsize, msg); |
438 | 0 | #endif /* HAVE_STRERROR */ |
439 | 0 | } |
440 | | #endif |
441 | | |
442 | | #if defined(HAVE_STRERROR_R) && defined(STRERROR_R_RC_INT) && !defined(BEOS) |
443 | | /* AIX and Tru64 style */ |
444 | | static char *native_strerror(apr_status_t statcode, char *buf, |
445 | | apr_size_t bufsize) |
446 | | { |
447 | | if (strerror_r(statcode, buf, bufsize) < 0) { |
448 | | return stuffbuffer(buf, bufsize, |
449 | | "APR does not understand this error code"); |
450 | | } |
451 | | else { |
452 | | return buf; |
453 | | } |
454 | | } |
455 | | #elif defined(HAVE_STRERROR_R) |
456 | | /* glibc style */ |
457 | | |
458 | | /* BeOS has the function available, but it doesn't provide |
459 | | * the prototype publicly (doh!), so to avoid a build warning |
460 | | * we add a suitable prototype here. |
461 | | */ |
462 | | #if defined(BEOS) |
463 | | const char *strerror_r(apr_status_t, char *, apr_size_t); |
464 | | #endif |
465 | | |
466 | | static char *native_strerror(apr_status_t statcode, char *buf, |
467 | | apr_size_t bufsize) |
468 | 0 | { |
469 | 0 | const char *msg; |
470 | |
|
471 | 0 | buf[0] = '\0'; |
472 | 0 | msg = strerror_r(statcode, buf, bufsize); |
473 | 0 | if (buf[0] == '\0') { /* libc didn't use our buffer */ |
474 | 0 | return stuffbuffer(buf, bufsize, msg); |
475 | 0 | } |
476 | 0 | else { |
477 | 0 | return buf; |
478 | 0 | } |
479 | 0 | } |
480 | | #else |
481 | | /* plain old strerror(); |
482 | | * thread-safe on some platforms (e.g., Solaris, OS/390) |
483 | | */ |
484 | | static char *native_strerror(apr_status_t statcode, char *buf, |
485 | | apr_size_t bufsize) |
486 | | { |
487 | | const char *err = strerror(statcode); |
488 | | if (err) { |
489 | | return stuffbuffer(buf, bufsize, err); |
490 | | } else { |
491 | | return stuffbuffer(buf, bufsize, |
492 | | "APR does not understand this error code"); |
493 | | } |
494 | | } |
495 | | #endif |
496 | | |
497 | | APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf, |
498 | | apr_size_t bufsize) |
499 | 0 | { |
500 | 0 | if (statcode < APR_OS_START_ERROR) { |
501 | 0 | return native_strerror(statcode, buf, bufsize); |
502 | 0 | } |
503 | 0 | else if (statcode < APR_OS_START_USERERR) { |
504 | 0 | return stuffbuffer(buf, bufsize, apr_error_string(statcode)); |
505 | 0 | } |
506 | 0 | else if (statcode < APR_OS_START_EAIERR) { |
507 | 0 | return stuffbuffer(buf, bufsize, "APR does not understand this error code"); |
508 | 0 | } |
509 | 0 | else if (statcode < APR_OS_START_SYSERR) { |
510 | 0 | #if defined(HAVE_GAI_STRERROR) |
511 | 0 | statcode -= APR_OS_START_EAIERR; |
512 | 0 | #if defined(NEGATIVE_EAI) |
513 | 0 | statcode = -statcode; |
514 | 0 | #endif |
515 | 0 | return stuffbuffer(buf, bufsize, gai_strerror(statcode)); |
516 | | #else |
517 | | return stuffbuffer(buf, bufsize, "APR does not understand this error code"); |
518 | | #endif |
519 | 0 | } |
520 | 0 | else { |
521 | 0 | return apr_os_strerror(buf, bufsize, statcode - APR_OS_START_SYSERR); |
522 | 0 | } |
523 | 0 | } |
524 | | |