bottleneck testcase based on rubbos
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / srclib / apr / misc / unix / errorcodes.c
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 #if APR_HAVE_NETDB_H
23 #include <netdb.h>
24 #endif
25 #ifdef HAVE_DLFCN_H
26 #include <dlfcn.h>
27 #endif
28
29 /*
30  * stuffbuffer - like apr_cpystrn() but returns the address of the
31  * dest buffer instead of the address of the terminating '\0'
32  */
33 static char *stuffbuffer(char *buf, apr_size_t bufsize, const char *s)
34 {
35     apr_cpystrn(buf,s,bufsize);
36     return buf;
37 }
38
39 static char *apr_error_string(apr_status_t statcode)
40 {
41     switch (statcode) {
42     case APR_ENOPOOL:
43         return "A new pool could not be created.";
44     case APR_EBADDATE:
45         return "An invalid date has been provided";
46     case APR_EINVALSOCK:
47         return "An invalid socket was returned";
48     case APR_ENOPROC:
49         return "No process was provided and one was required.";
50     case APR_ENOTIME:
51         return "No time was provided and one was required.";
52     case APR_ENODIR:
53         return "No directory was provided and one was required.";
54     case APR_ENOLOCK:
55         return "No lock was provided and one was required.";
56     case APR_ENOPOLL:
57         return "No poll structure was provided and one was required.";
58     case APR_ENOSOCKET:
59         return "No socket was provided and one was required.";
60     case APR_ENOTHREAD:
61         return "No thread was provided and one was required.";
62     case APR_ENOTHDKEY:
63         return "No thread key structure was provided and one was required.";
64     case APR_ENOSHMAVAIL:
65         return "No shared memory is currently available";
66     case APR_EDSOOPEN:
67 #if APR_HAS_DSO && defined(HAVE_LIBDL)
68         return dlerror();
69 #else
70         return "DSO load failed";
71 #endif /* HAVE_LIBDL */
72     case APR_EBADIP:
73         return "The specified IP address is invalid.";
74     case APR_EBADMASK:
75         return "The specified network mask is invalid.";
76
77     case APR_INCHILD:
78         return
79             "Your code just forked, and you are currently executing in the "
80             "child process";
81     case APR_INPARENT:
82         return
83             "Your code just forked, and you are currently executing in the "
84             "parent process";
85     case APR_DETACH:
86         return "The specified thread is detached";
87     case APR_NOTDETACH:
88         return "The specified thread is not detached";
89     case APR_CHILD_DONE:
90         return "The specified child process is done executing";
91     case APR_CHILD_NOTDONE:
92         return "The specified child process is not done executing";
93     case APR_TIMEUP:
94         return "The timeout specified has expired";
95     case APR_INCOMPLETE:
96         return "Partial results are valid but processing is incomplete";
97     case APR_BADCH:
98         return "Bad character specified on command line";
99     case APR_BADARG:
100         return "Missing parameter for the specified command line option";
101     case APR_EOF:
102         return "End of file found";
103     case APR_NOTFOUND:
104         return "Could not find specified socket in poll list.";
105     case APR_ANONYMOUS:
106         return "Shared memory is implemented anonymously";
107     case APR_FILEBASED:
108         return "Shared memory is implemented using files";
109     case APR_KEYBASED:
110         return "Shared memory is implemented using a key system";
111     case APR_EINIT:
112         return
113             "There is no error, this value signifies an initialized "
114             "error code";
115     case APR_ENOTIMPL:
116         return "This function has not been implemented on this platform";
117     case APR_EMISMATCH:
118         return "passwords do not match";
119     case APR_EABSOLUTE:
120         return "The given path is absolute";
121     case APR_ERELATIVE:
122         return "The given path is relative";
123     case APR_EINCOMPLETE:
124         return "The given path is incomplete";
125     case APR_EABOVEROOT:
126         return "The given path was above the root path";
127     case APR_EBADPATH:
128         return "The given path misformatted or contained invalid characters";
129     case APR_EPATHWILD:
130         return "The given path contained wildcard characters";
131     case APR_EPROC_UNKNOWN:
132         return "The process is not recognized.";
133     default:
134         return "Error string not specified yet";
135     }
136 }
137
138
139 #ifdef OS2
140 #include <ctype.h>
141
142 int apr_canonical_error(apr_status_t err);
143
144 static char *apr_os_strerror(char* buf, apr_size_t bufsize, int err)
145 {
146   char result[200];
147   unsigned char message[HUGE_STRING_LEN];
148   ULONG len;
149   char *pos;
150   int c;
151   
152   if (err >= 10000 && err < 12000) {  /* socket error codes */
153       return stuffbuffer(buf, bufsize,
154                          strerror(apr_canonical_error(err+APR_OS_START_SYSERR)));
155   } 
156   else if (DosGetMessage(NULL, 0, message, HUGE_STRING_LEN, err,
157                          "OSO001.MSG", &len) == 0) {
158       len--;
159       message[len] = 0;
160       pos = result;
161   
162       if (len >= sizeof(result))
163         len = sizeof(result-1);
164
165       for (c=0; c<len; c++) {
166           /* skip multiple whitespace */
167           while (apr_isspace(message[c]) && apr_isspace(message[c+1]))
168               c++;
169           *(pos++) = apr_isspace(message[c]) ? ' ' : message[c];
170       }
171   
172       *pos = 0;
173   } 
174   else {
175       sprintf(result, "OS/2 error %d", err);
176   }
177
178   /* Stuff the string into the caller supplied buffer, then return 
179    * a pointer to it.
180    */
181   return stuffbuffer(buf, bufsize, result);  
182 }
183
184 #elif defined(WIN32) || defined(NETWARE)
185
186 static const struct {
187     apr_status_t code;
188     const char *msg;
189 } gaErrorList[] = {
190     WSAEINTR,           "Interrupted system call",
191     WSAEBADF,           "Bad file number",
192     WSAEACCES,          "Permission denied",
193     WSAEFAULT,          "Bad address",
194     WSAEINVAL,          "Invalid argument",
195     WSAEMFILE,          "Too many open sockets",
196     WSAEWOULDBLOCK,     "Operation would block",
197     WSAEINPROGRESS,     "Operation now in progress",
198     WSAEALREADY,        "Operation already in progress",
199     WSAENOTSOCK,        "Socket operation on non-socket",
200     WSAEDESTADDRREQ,    "Destination address required",
201     WSAEMSGSIZE,        "Message too long",
202     WSAEPROTOTYPE,      "Protocol wrong type for socket",
203     WSAENOPROTOOPT,     "Bad protocol option",
204     WSAEPROTONOSUPPORT, "Protocol not supported",
205     WSAESOCKTNOSUPPORT, "Socket type not supported",
206     WSAEOPNOTSUPP,      "Operation not supported on socket",
207     WSAEPFNOSUPPORT,    "Protocol family not supported",
208     WSAEAFNOSUPPORT,    "Address family not supported",
209     WSAEADDRINUSE,      "Address already in use",
210     WSAEADDRNOTAVAIL,   "Can't assign requested address",
211     WSAENETDOWN,        "Network is down",
212     WSAENETUNREACH,     "Network is unreachable",
213     WSAENETRESET,       "Net connection reset",
214     WSAECONNABORTED,    "Software caused connection abort",
215     WSAECONNRESET,      "Connection reset by peer",
216     WSAENOBUFS,         "No buffer space available",
217     WSAEISCONN,         "Socket is already connected",
218     WSAENOTCONN,        "Socket is not connected",
219     WSAESHUTDOWN,       "Can't send after socket shutdown",
220     WSAETOOMANYREFS,    "Too many references, can't splice",
221     WSAETIMEDOUT,       "Connection timed out",
222     WSAECONNREFUSED,    "Connection refused",
223     WSAELOOP,           "Too many levels of symbolic links",
224     WSAENAMETOOLONG,    "File name too long",
225     WSAEHOSTDOWN,       "Host is down",
226     WSAEHOSTUNREACH,    "No route to host",
227     WSAENOTEMPTY,       "Directory not empty",
228     WSAEPROCLIM,        "Too many processes",
229     WSAEUSERS,          "Too many users",
230     WSAEDQUOT,          "Disc quota exceeded",
231     WSAESTALE,          "Stale NFS file handle",
232     WSAEREMOTE,         "Too many levels of remote in path",
233     WSASYSNOTREADY,     "Network system is unavailable",
234     WSAVERNOTSUPPORTED, "Winsock version out of range",
235     WSANOTINITIALISED,  "WSAStartup not yet called",
236     WSAEDISCON,         "Graceful shutdown in progress",
237     WSAHOST_NOT_FOUND,  "Host not found",
238     WSANO_DATA,         "No host data of that type was found",
239     0,                  NULL
240 };
241
242
243 static char *apr_os_strerror(char *buf, apr_size_t bufsize, apr_status_t errcode)
244 {
245     apr_size_t len=0, i;
246
247 #ifndef NETWARE
248     len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM 
249                       | FORMAT_MESSAGE_IGNORE_INSERTS,
250                         NULL,
251                         errcode,
252                         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
253                         (LPTSTR) buf,
254                         (DWORD)bufsize,
255                         NULL);
256 #endif
257
258     if (!len) {
259         for (i = 0; gaErrorList[i].msg; ++i) {
260             if (gaErrorList[i].code == errcode) {
261                 apr_cpystrn(buf, gaErrorList[i].msg, bufsize);
262                 len = strlen(buf);
263                 break;
264             }
265         }
266     }
267
268     if (len) {
269         /* FormatMessage put the message in the buffer, but it may
270          * have embedded a newline (\r\n), and possible more than one.
271          * Remove the newlines replacing them with a space. This is not
272          * as visually perfect as moving all the remaining message over,
273          * but more efficient.
274          */
275         i = len;
276         while (i) {
277             i--;
278             if ((buf[i] == '\r') || (buf[i] == '\n'))
279                 buf[i] = ' ';
280         }
281     }
282     else {
283         /* Windows didn't provide us with a message.  Even stuff like                    * WSAECONNREFUSED won't get a message.
284          */
285         apr_snprintf(buf, bufsize, "Unrecognized Win32 error code %d", errcode);
286     }
287
288     return buf;
289 }
290
291 #else
292 /* On Unix, apr_os_strerror() handles error codes from the resolver 
293  * (h_errno). 
294  */
295 static char *apr_os_strerror(char* buf, apr_size_t bufsize, int err) 
296 {
297 #ifdef HAVE_HSTRERROR
298     return stuffbuffer(buf, bufsize, hstrerror(err));
299 #else /* HAVE_HSTRERROR */
300     const char *msg;
301
302     switch(err) {
303     case HOST_NOT_FOUND:
304         msg = "Unknown host";
305         break;
306 #if defined(NO_DATA)
307     case NO_DATA:
308 #if defined(NO_ADDRESS) && (NO_DATA != NO_ADDRESS)
309     case NO_ADDRESS:
310 #endif
311         msg = "No address for host";
312         break;
313 #elif defined(NO_ADDRESS)
314     case NO_ADDRESS:
315         msg = "No address for host";
316         break;
317 #endif /* NO_DATA */
318     default:
319         msg = "Unrecognized resolver error";
320     }
321     return stuffbuffer(buf, bufsize, msg);
322 #endif /* HAVE_STRERROR */
323 }
324 #endif
325
326 #if defined(HAVE_STRERROR_R) && defined(STRERROR_R_RC_INT) && !defined(BEOS)
327 /* AIX and Tru64 style */
328 static char *native_strerror(apr_status_t statcode, char *buf,
329                              apr_size_t bufsize)
330 {
331     if (strerror_r(statcode, buf, bufsize) < 0) {
332         return stuffbuffer(buf, bufsize, 
333                            "APR does not understand this error code");
334     }
335     else {
336         return buf;
337     }
338 }
339 #elif defined(HAVE_STRERROR_R)
340 /* glibc style */
341
342 /* BeOS has the function available, but it doesn't provide
343  * the prototype publically (doh!), so to avoid a build warning
344  * we add a suitable prototype here.
345  */
346 #if defined(BEOS)
347 const char *strerror_r(apr_status_t, char *, apr_size_t);
348 #endif
349
350 static char *native_strerror(apr_status_t statcode, char *buf,
351                              apr_size_t bufsize)
352 {
353     const char *msg;
354
355     buf[0] = '\0';
356     msg = strerror_r(statcode, buf, bufsize);
357     if (buf[0] == '\0') { /* libc didn't use our buffer */
358         return stuffbuffer(buf, bufsize, msg);
359     }
360     else {
361         return buf;
362     }
363 }
364 #else
365 /* plain old strerror(); 
366  * thread-safe on some platforms (e.g., Solaris, OS/390)
367  */
368 static char *native_strerror(apr_status_t statcode, char *buf,
369                              apr_size_t bufsize)
370 {
371 #ifdef _WIN32_WCE
372     static char err[32];
373     sprintf(err, "Native Error #%d", statcode);
374     return stuffbuffer(buf, bufsize, err);
375 #else
376     const char *err = strerror(statcode);
377     if (err) {
378         return stuffbuffer(buf, bufsize, err);
379     } else {
380         return stuffbuffer(buf, bufsize, 
381                            "APR does not understand this error code");
382     }
383 #endif
384 }
385 #endif
386
387 APR_DECLARE(char *) apr_strerror(apr_status_t statcode, char *buf,
388                                  apr_size_t bufsize)
389 {
390     if (statcode < APR_OS_START_ERROR) {
391         return native_strerror(statcode, buf, bufsize);
392     }
393     else if (statcode < APR_OS_START_USERERR) {
394         return stuffbuffer(buf, bufsize, apr_error_string(statcode));
395     }
396     else if (statcode < APR_OS_START_EAIERR) {
397         return stuffbuffer(buf, bufsize, "APR does not understand this error code");
398     }
399     else if (statcode < APR_OS_START_SYSERR) {
400 #if defined(HAVE_GAI_STRERROR)
401         statcode -= APR_OS_START_EAIERR;
402 #if defined(NEGATIVE_EAI)
403         statcode = -statcode;
404 #endif
405         return stuffbuffer(buf, bufsize, gai_strerror(statcode));
406 #else
407         return stuffbuffer(buf, bufsize, "APR does not understand this error code");
408 #endif
409     }
410     else {
411         return apr_os_strerror(buf, bufsize, statcode - APR_OS_START_SYSERR);
412     }
413 }
414