1/* strerror.c --- POSIX compatible system error routine
2
3   Copyright (C) 2007-2010 Free Software Foundation, Inc.
4
5   This program is free software: you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 3 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18#include <config.h>
19
20#include <string.h>
21
22#if REPLACE_STRERROR
23
24# include <errno.h>
25# include <stdio.h>
26
27# if GNULIB_defined_ESOCK /* native Windows platforms */
28#  if HAVE_WINSOCK2_H
29#   include <winsock2.h>
30#  endif
31# endif
32
33# include "intprops.h"
34
35# undef strerror
36# if ! HAVE_DECL_STRERROR
37#  define strerror(n) NULL
38# endif
39
40char *
41rpl_strerror (int n)
42{
43  char const *msg = NULL;
44  /* These error messages are taken from glibc/sysdeps/gnu/errlist.c.  */
45  switch (n)
46    {
47# if GNULIB_defined_ETXTBSY
48    case ETXTBSY:
49      msg = "Text file busy";
50      break;
51# endif
52
53# if GNULIB_defined_ESOCK /* native Windows platforms */
54    /* EWOULDBLOCK is the same as EAGAIN.  */
55    case EINPROGRESS:
56      msg = "Operation now in progress";
57      break;
58    case EALREADY:
59      msg = "Operation already in progress";
60      break;
61    case ENOTSOCK:
62      msg = "Socket operation on non-socket";
63      break;
64    case EDESTADDRREQ:
65      msg = "Destination address required";
66      break;
67    case EMSGSIZE:
68      msg = "Message too long";
69      break;
70    case EPROTOTYPE:
71      msg = "Protocol wrong type for socket";
72      break;
73    case ENOPROTOOPT:
74      msg = "Protocol not available";
75      break;
76    case EPROTONOSUPPORT:
77      msg = "Protocol not supported";
78      break;
79    case ESOCKTNOSUPPORT:
80      msg = "Socket type not supported";
81      break;
82    case EOPNOTSUPP:
83      msg = "Operation not supported";
84      break;
85    case EPFNOSUPPORT:
86      msg = "Protocol family not supported";
87      break;
88    case EAFNOSUPPORT:
89      msg = "Address family not supported by protocol";
90      break;
91    case EADDRINUSE:
92      msg = "Address already in use";
93      break;
94    case EADDRNOTAVAIL:
95      msg = "Cannot assign requested address";
96      break;
97    case ENETDOWN:
98      msg = "Network is down";
99      break;
100    case ENETUNREACH:
101      msg = "Network is unreachable";
102      break;
103    case ENETRESET:
104      msg = "Network dropped connection on reset";
105      break;
106    case ECONNABORTED:
107      msg = "Software caused connection abort";
108      break;
109    case ECONNRESET:
110      msg = "Connection reset by peer";
111      break;
112    case ENOBUFS:
113      msg = "No buffer space available";
114      break;
115    case EISCONN:
116      msg = "Transport endpoint is already connected";
117      break;
118    case ENOTCONN:
119      msg = "Transport endpoint is not connected";
120      break;
121    case ESHUTDOWN:
122      msg = "Cannot send after transport endpoint shutdown";
123      break;
124    case ETOOMANYREFS:
125      msg = "Too many references: cannot splice";
126      break;
127    case ETIMEDOUT:
128      msg = "Connection timed out";
129      break;
130    case ECONNREFUSED:
131      msg = "Connection refused";
132      break;
133    case ELOOP:
134      msg = "Too many levels of symbolic links";
135      break;
136    case EHOSTDOWN:
137      msg = "Host is down";
138      break;
139    case EHOSTUNREACH:
140      msg = "No route to host";
141      break;
142    case EPROCLIM:
143      msg = "Too many processes";
144      break;
145    case EUSERS:
146      msg = "Too many users";
147      break;
148    case EDQUOT:
149      msg = "Disk quota exceeded";
150      break;
151    case ESTALE:
152      msg = "Stale NFS file handle";
153      break;
154    case EREMOTE:
155      msg = "Object is remote";
156      break;
157#  if HAVE_WINSOCK2_H
158    /* WSA_INVALID_HANDLE maps to EBADF */
159    /* WSA_NOT_ENOUGH_MEMORY maps to ENOMEM */
160    /* WSA_INVALID_PARAMETER maps to EINVAL */
161    case WSA_OPERATION_ABORTED:
162      msg = "Overlapped operation aborted";
163      break;
164    case WSA_IO_INCOMPLETE:
165      msg = "Overlapped I/O event object not in signaled state";
166      break;
167    case WSA_IO_PENDING:
168      msg = "Overlapped operations will complete later";
169      break;
170    /* WSAEINTR maps to EINTR */
171    /* WSAEBADF maps to EBADF */
172    /* WSAEACCES maps to EACCES */
173    /* WSAEFAULT maps to EFAULT */
174    /* WSAEINVAL maps to EINVAL */
175    /* WSAEMFILE maps to EMFILE */
176    /* WSAEWOULDBLOCK maps to EWOULDBLOCK */
177    /* WSAEINPROGRESS is EINPROGRESS */
178    /* WSAEALREADY is EALREADY */
179    /* WSAENOTSOCK is ENOTSOCK */
180    /* WSAEDESTADDRREQ is EDESTADDRREQ */
181    /* WSAEMSGSIZE is EMSGSIZE */
182    /* WSAEPROTOTYPE is EPROTOTYPE */
183    /* WSAENOPROTOOPT is ENOPROTOOPT */
184    /* WSAEPROTONOSUPPORT is EPROTONOSUPPORT */
185    /* WSAESOCKTNOSUPPORT is ESOCKTNOSUPPORT */
186    /* WSAEOPNOTSUPP is EOPNOTSUPP */
187    /* WSAEPFNOSUPPORT is EPFNOSUPPORT */
188    /* WSAEAFNOSUPPORT is EAFNOSUPPORT */
189    /* WSAEADDRINUSE is EADDRINUSE */
190    /* WSAEADDRNOTAVAIL is EADDRNOTAVAIL */
191    /* WSAENETDOWN is ENETDOWN */
192    /* WSAENETUNREACH is ENETUNREACH */
193    /* WSAENETRESET is ENETRESET */
194    /* WSAECONNABORTED is ECONNABORTED */
195    /* WSAECONNRESET is ECONNRESET */
196    /* WSAENOBUFS is ENOBUFS */
197    /* WSAEISCONN is EISCONN */
198    /* WSAENOTCONN is ENOTCONN */
199    /* WSAESHUTDOWN is ESHUTDOWN */
200    /* WSAETOOMANYREFS is ETOOMANYREFS */
201    /* WSAETIMEDOUT is ETIMEDOUT */
202    /* WSAECONNREFUSED is ECONNREFUSED */
203    /* WSAELOOP is ELOOP */
204    /* WSAENAMETOOLONG maps to ENAMETOOLONG */
205    /* WSAEHOSTDOWN is EHOSTDOWN */
206    /* WSAEHOSTUNREACH is EHOSTUNREACH */
207    /* WSAENOTEMPTY maps to ENOTEMPTY */
208    /* WSAEPROCLIM is EPROCLIM */
209    /* WSAEUSERS is EUSERS */
210    /* WSAEDQUOT is EDQUOT */
211    /* WSAESTALE is ESTALE */
212    /* WSAEREMOTE is EREMOTE */
213    case WSASYSNOTREADY:
214      msg = "Network subsystem is unavailable";
215      break;
216    case WSAVERNOTSUPPORTED:
217      msg = "Winsock.dll version out of range";
218      break;
219    case WSANOTINITIALISED:
220      msg = "Successful WSAStartup not yet performed";
221      break;
222    case WSAEDISCON:
223      msg = "Graceful shutdown in progress";
224      break;
225    case WSAENOMORE: case WSA_E_NO_MORE:
226      msg = "No more results";
227      break;
228    case WSAECANCELLED: case WSA_E_CANCELLED:
229      msg = "Call was canceled";
230      break;
231    case WSAEINVALIDPROCTABLE:
232      msg = "Procedure call table is invalid";
233      break;
234    case WSAEINVALIDPROVIDER:
235      msg = "Service provider is invalid";
236      break;
237    case WSAEPROVIDERFAILEDINIT:
238      msg = "Service provider failed to initialize";
239      break;
240    case WSASYSCALLFAILURE:
241      msg = "System call failure";
242      break;
243    case WSASERVICE_NOT_FOUND:
244      msg = "Service not found";
245      break;
246    case WSATYPE_NOT_FOUND:
247      msg = "Class type not found";
248      break;
249    case WSAEREFUSED:
250      msg = "Database query was refused";
251      break;
252    case WSAHOST_NOT_FOUND:
253      msg = "Host not found";
254      break;
255    case WSATRY_AGAIN:
256      msg = "Nonauthoritative host not found";
257      break;
258    case WSANO_RECOVERY:
259      msg = "Nonrecoverable error";
260      break;
261    case WSANO_DATA:
262      msg = "Valid name, no data record of requested type";
263      break;
264    /* WSA_QOS_* omitted */
265#  endif
266# endif
267
268# if GNULIB_defined_ENOMSG
269    case ENOMSG:
270      msg = "No message of desired type";
271      break;
272# endif
273
274# if GNULIB_defined_EIDRM
275    case EIDRM:
276      msg = "Identifier removed";
277      break;
278# endif
279
280# if GNULIB_defined_ENOLINK
281    case ENOLINK:
282      msg = "Link has been severed";
283      break;
284# endif
285
286# if GNULIB_defined_EPROTO
287    case EPROTO:
288      msg = "Protocol error";
289      break;
290# endif
291
292# if GNULIB_defined_EMULTIHOP
293    case EMULTIHOP:
294      msg = "Multihop attempted";
295      break;
296# endif
297
298# if GNULIB_defined_EBADMSG
299    case EBADMSG:
300      msg = "Bad message";
301      break;
302# endif
303
304# if GNULIB_defined_EOVERFLOW
305    case EOVERFLOW:
306      msg = "Value too large for defined data type";
307      break;
308# endif
309
310# if GNULIB_defined_ENOTSUP
311    case ENOTSUP:
312      msg = "Not supported";
313      break;
314# endif
315
316# if GNULIB_defined_ESTALE
317    case ESTALE:
318      msg = "Stale NFS file handle";
319      break;
320# endif
321
322# if GNULIB_defined_ECANCELED
323    case ECANCELED:
324      msg = "Operation canceled";
325      break;
326# endif
327    }
328
329  if (msg)
330    return (char *) msg;
331
332  {
333    char *result = strerror (n);
334
335    if (result == NULL || result[0] == '\0')
336      {
337        static char const fmt[] = "Unknown error (%d)";
338        static char msg_buf[sizeof fmt + INT_STRLEN_BOUND (n)];
339        sprintf (msg_buf, fmt, n);
340        return msg_buf;
341      }
342
343    return result;
344  }
345}
346
347#endif
348