strerror_r: fix missing header
[gnulib.git] / lib / strerror_r.c
1 /* strerror_r.c --- POSIX compatible system error routine
2
3    Copyright (C) 2010-2011 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 /* Written by Bruno Haible <bruno@clisp.org>, 2010.  */
19
20 #include <config.h>
21
22 /* Enable declaration of sys_nerr and sys_errlist in <errno.h> on NetBSD.  */
23 #define _NETBSD_SOURCE 1
24
25 /* Specification.  */
26 #include <string.h>
27
28 #include <errno.h>
29 #include <stdio.h>
30
31 #if GNULIB_defined_ESOCK /* native Windows platforms */
32 # if HAVE_WINSOCK2_H
33 #  include <winsock2.h>
34 # endif
35 #endif
36
37 /* Reasonable buffer size that should never trigger ERANGE; if this
38    proves too small, we intentionally abort(), to remind us to fix
39    this value as well as strerror-impl.h.  */
40 #define STACKBUF_LEN 256
41
42 #if (__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__) && HAVE___XPG_STRERROR_R /* glibc >= 2.3.4, cygwin >= 1.7.9 */
43
44 # define USE_XPG_STRERROR_R 1
45
46 #elif HAVE_DECL_STRERROR_R && !(__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__)
47
48 /* The system's strerror_r function is OK, except that its third argument
49    is 'int', not 'size_t', or its return type is wrong.  */
50
51 # include <limits.h>
52
53 # define USE_SYSTEM_STRERROR_R 1
54
55 #else /* (__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__ ? !HAVE___XPG_STRERROR_R : !HAVE_DECL_STRERROR_R) */
56
57 /* Use the system's strerror().  Exclude glibc and cygwin because the
58    system strerror_r has the wrong return type, and cygwin 1.7.9
59    strerror_r clobbers strerror.  */
60 # undef strerror
61
62 # define USE_SYSTEM_STRERROR 1
63
64 # if defined __NetBSD__ || defined __hpux || ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __sgi || (defined __sun && !defined _LP64) || defined __CYGWIN__
65
66 /* No locking needed.  */
67
68 /* Get catgets internationalization functions.  */
69 #  if HAVE_CATGETS
70 #   include <nl_types.h>
71 #  endif
72
73 /* Get sys_nerr, sys_errlist on HP-UX (otherwise only declared in C++ mode).
74    Get sys_nerr, sys_errlist on IRIX (otherwise only declared with _SGIAPI).  */
75 #  if defined __hpux || defined __sgi
76 extern int sys_nerr;
77 extern char *sys_errlist[];
78 #  endif
79
80 /* Get sys_nerr on Solaris.  */
81 #  if defined __sun && !defined _LP64
82 extern int sys_nerr;
83 #  endif
84
85 /* Get sys_nerr, sys_errlist on native Windows.  */
86 #  include <stdlib.h>
87
88 # else
89
90 #  include "glthread/lock.h"
91
92 /* This lock protects the buffer returned by strerror().  We assume that
93    no other uses of strerror() exist in the program.  */
94 gl_lock_define_initialized(static, strerror_lock)
95
96 # endif
97
98 #endif
99
100 /* Copy as much of MSG into BUF as possible, without corrupting errno.
101    Return 0 if MSG fit in BUFLEN, otherwise return ERANGE.  */
102 static int
103 safe_copy (char *buf, size_t buflen, const char *msg)
104 {
105   size_t len = strlen (msg);
106   int ret;
107
108   if (len < buflen)
109     {
110       /* Although POSIX allows memcpy() to corrupt errno, we don't
111          know of any implementation where this is a real problem.  */
112       memcpy (buf, msg, len + 1);
113       ret = 0;
114     }
115   else
116     {
117       memcpy (buf, msg, buflen - 1);
118       buf[buflen - 1] = '\0';
119       ret = ERANGE;
120     }
121   return ret;
122 }
123
124
125 int
126 strerror_r (int errnum, char *buf, size_t buflen)
127 #undef strerror_r
128 {
129   /* Filter this out now, so that rest of this replacement knows that
130      there is room for a non-empty message and trailing NUL.  */
131   if (buflen <= 1)
132     {
133       if (buflen)
134         *buf = '\0';
135       return ERANGE;
136     }
137   *buf = '\0';
138
139 #if GNULIB_defined_ETXTBSY \
140     || GNULIB_defined_ESOCK \
141     || GNULIB_defined_ENOMSG \
142     || GNULIB_defined_EIDRM \
143     || GNULIB_defined_ENOLINK \
144     || GNULIB_defined_EPROTO \
145     || GNULIB_defined_EMULTIHOP \
146     || GNULIB_defined_EBADMSG \
147     || GNULIB_defined_EOVERFLOW \
148     || GNULIB_defined_ENOTSUP \
149     || GNULIB_defined_ESTALE \
150     || GNULIB_defined_EDQUOT \
151     || GNULIB_defined_ECANCELED
152   {
153     char const *msg = NULL;
154     /* These error messages are taken from glibc/sysdeps/gnu/errlist.c.  */
155     switch (errnum)
156       {
157 # if GNULIB_defined_ETXTBSY
158       case ETXTBSY:
159         msg = "Text file busy";
160         break;
161 # endif
162
163 # if GNULIB_defined_ESOCK /* native Windows platforms */
164       /* EWOULDBLOCK is the same as EAGAIN.  */
165       case EINPROGRESS:
166         msg = "Operation now in progress";
167         break;
168       case EALREADY:
169         msg = "Operation already in progress";
170         break;
171       case ENOTSOCK:
172         msg = "Socket operation on non-socket";
173         break;
174       case EDESTADDRREQ:
175         msg = "Destination address required";
176         break;
177       case EMSGSIZE:
178         msg = "Message too long";
179         break;
180       case EPROTOTYPE:
181         msg = "Protocol wrong type for socket";
182         break;
183       case ENOPROTOOPT:
184         msg = "Protocol not available";
185         break;
186       case EPROTONOSUPPORT:
187         msg = "Protocol not supported";
188         break;
189       case ESOCKTNOSUPPORT:
190         msg = "Socket type not supported";
191         break;
192       case EOPNOTSUPP:
193         msg = "Operation not supported";
194         break;
195       case EPFNOSUPPORT:
196         msg = "Protocol family not supported";
197         break;
198       case EAFNOSUPPORT:
199         msg = "Address family not supported by protocol";
200         break;
201       case EADDRINUSE:
202         msg = "Address already in use";
203         break;
204       case EADDRNOTAVAIL:
205         msg = "Cannot assign requested address";
206         break;
207       case ENETDOWN:
208         msg = "Network is down";
209         break;
210       case ENETUNREACH:
211         msg = "Network is unreachable";
212         break;
213       case ENETRESET:
214         msg = "Network dropped connection on reset";
215         break;
216       case ECONNABORTED:
217         msg = "Software caused connection abort";
218         break;
219       case ECONNRESET:
220         msg = "Connection reset by peer";
221         break;
222       case ENOBUFS:
223         msg = "No buffer space available";
224         break;
225       case EISCONN:
226         msg = "Transport endpoint is already connected";
227         break;
228       case ENOTCONN:
229         msg = "Transport endpoint is not connected";
230         break;
231       case ESHUTDOWN:
232         msg = "Cannot send after transport endpoint shutdown";
233         break;
234       case ETOOMANYREFS:
235         msg = "Too many references: cannot splice";
236         break;
237       case ETIMEDOUT:
238         msg = "Connection timed out";
239         break;
240       case ECONNREFUSED:
241         msg = "Connection refused";
242         break;
243       case ELOOP:
244         msg = "Too many levels of symbolic links";
245         break;
246       case EHOSTDOWN:
247         msg = "Host is down";
248         break;
249       case EHOSTUNREACH:
250         msg = "No route to host";
251         break;
252       case EPROCLIM:
253         msg = "Too many processes";
254         break;
255       case EUSERS:
256         msg = "Too many users";
257         break;
258       case EDQUOT:
259         msg = "Disk quota exceeded";
260         break;
261       case ESTALE:
262         msg = "Stale NFS file handle";
263         break;
264       case EREMOTE:
265         msg = "Object is remote";
266         break;
267 #  if HAVE_WINSOCK2_H
268       /* WSA_INVALID_HANDLE maps to EBADF */
269       /* WSA_NOT_ENOUGH_MEMORY maps to ENOMEM */
270       /* WSA_INVALID_PARAMETER maps to EINVAL */
271       case WSA_OPERATION_ABORTED:
272         msg = "Overlapped operation aborted";
273         break;
274       case WSA_IO_INCOMPLETE:
275         msg = "Overlapped I/O event object not in signaled state";
276         break;
277       case WSA_IO_PENDING:
278         msg = "Overlapped operations will complete later";
279         break;
280       /* WSAEINTR maps to EINTR */
281       /* WSAEBADF maps to EBADF */
282       /* WSAEACCES maps to EACCES */
283       /* WSAEFAULT maps to EFAULT */
284       /* WSAEINVAL maps to EINVAL */
285       /* WSAEMFILE maps to EMFILE */
286       /* WSAEWOULDBLOCK maps to EWOULDBLOCK */
287       /* WSAEINPROGRESS is EINPROGRESS */
288       /* WSAEALREADY is EALREADY */
289       /* WSAENOTSOCK is ENOTSOCK */
290       /* WSAEDESTADDRREQ is EDESTADDRREQ */
291       /* WSAEMSGSIZE is EMSGSIZE */
292       /* WSAEPROTOTYPE is EPROTOTYPE */
293       /* WSAENOPROTOOPT is ENOPROTOOPT */
294       /* WSAEPROTONOSUPPORT is EPROTONOSUPPORT */
295       /* WSAESOCKTNOSUPPORT is ESOCKTNOSUPPORT */
296       /* WSAEOPNOTSUPP is EOPNOTSUPP */
297       /* WSAEPFNOSUPPORT is EPFNOSUPPORT */
298       /* WSAEAFNOSUPPORT is EAFNOSUPPORT */
299       /* WSAEADDRINUSE is EADDRINUSE */
300       /* WSAEADDRNOTAVAIL is EADDRNOTAVAIL */
301       /* WSAENETDOWN is ENETDOWN */
302       /* WSAENETUNREACH is ENETUNREACH */
303       /* WSAENETRESET is ENETRESET */
304       /* WSAECONNABORTED is ECONNABORTED */
305       /* WSAECONNRESET is ECONNRESET */
306       /* WSAENOBUFS is ENOBUFS */
307       /* WSAEISCONN is EISCONN */
308       /* WSAENOTCONN is ENOTCONN */
309       /* WSAESHUTDOWN is ESHUTDOWN */
310       /* WSAETOOMANYREFS is ETOOMANYREFS */
311       /* WSAETIMEDOUT is ETIMEDOUT */
312       /* WSAECONNREFUSED is ECONNREFUSED */
313       /* WSAELOOP is ELOOP */
314       /* WSAENAMETOOLONG maps to ENAMETOOLONG */
315       /* WSAEHOSTDOWN is EHOSTDOWN */
316       /* WSAEHOSTUNREACH is EHOSTUNREACH */
317       /* WSAENOTEMPTY maps to ENOTEMPTY */
318       /* WSAEPROCLIM is EPROCLIM */
319       /* WSAEUSERS is EUSERS */
320       /* WSAEDQUOT is EDQUOT */
321       /* WSAESTALE is ESTALE */
322       /* WSAEREMOTE is EREMOTE */
323       case WSASYSNOTREADY:
324         msg = "Network subsystem is unavailable";
325         break;
326       case WSAVERNOTSUPPORTED:
327         msg = "Winsock.dll version out of range";
328         break;
329       case WSANOTINITIALISED:
330         msg = "Successful WSAStartup not yet performed";
331         break;
332       case WSAEDISCON:
333         msg = "Graceful shutdown in progress";
334         break;
335       case WSAENOMORE: case WSA_E_NO_MORE:
336         msg = "No more results";
337         break;
338       case WSAECANCELLED: case WSA_E_CANCELLED:
339         msg = "Call was canceled";
340         break;
341       case WSAEINVALIDPROCTABLE:
342         msg = "Procedure call table is invalid";
343         break;
344       case WSAEINVALIDPROVIDER:
345         msg = "Service provider is invalid";
346         break;
347       case WSAEPROVIDERFAILEDINIT:
348         msg = "Service provider failed to initialize";
349         break;
350       case WSASYSCALLFAILURE:
351         msg = "System call failure";
352         break;
353       case WSASERVICE_NOT_FOUND:
354         msg = "Service not found";
355         break;
356       case WSATYPE_NOT_FOUND:
357         msg = "Class type not found";
358         break;
359       case WSAEREFUSED:
360         msg = "Database query was refused";
361         break;
362       case WSAHOST_NOT_FOUND:
363         msg = "Host not found";
364         break;
365       case WSATRY_AGAIN:
366         msg = "Nonauthoritative host not found";
367         break;
368       case WSANO_RECOVERY:
369         msg = "Nonrecoverable error";
370         break;
371       case WSANO_DATA:
372         msg = "Valid name, no data record of requested type";
373         break;
374       /* WSA_QOS_* omitted */
375 #  endif
376 # endif
377
378 # if GNULIB_defined_ENOMSG
379       case ENOMSG:
380         msg = "No message of desired type";
381         break;
382 # endif
383
384 # if GNULIB_defined_EIDRM
385       case EIDRM:
386         msg = "Identifier removed";
387         break;
388 # endif
389
390 # if GNULIB_defined_ENOLINK
391       case ENOLINK:
392         msg = "Link has been severed";
393         break;
394 # endif
395
396 # if GNULIB_defined_EPROTO
397       case EPROTO:
398         msg = "Protocol error";
399         break;
400 # endif
401
402 # if GNULIB_defined_EMULTIHOP
403       case EMULTIHOP:
404         msg = "Multihop attempted";
405         break;
406 # endif
407
408 # if GNULIB_defined_EBADMSG
409       case EBADMSG:
410         msg = "Bad message";
411         break;
412 # endif
413
414 # if GNULIB_defined_EOVERFLOW
415       case EOVERFLOW:
416         msg = "Value too large for defined data type";
417         break;
418 # endif
419
420 # if GNULIB_defined_ENOTSUP
421       case ENOTSUP:
422         msg = "Not supported";
423         break;
424 # endif
425
426 # if GNULIB_defined_ESTALE
427       case ESTALE:
428         msg = "Stale NFS file handle";
429         break;
430 # endif
431
432 # if GNULIB_defined_EDQUOT
433       case EDQUOT:
434         msg = "Disk quota exceeded";
435         break;
436 # endif
437
438 # if GNULIB_defined_ECANCELED
439       case ECANCELED:
440         msg = "Operation canceled";
441         break;
442 # endif
443       }
444
445     if (msg)
446       return safe_copy (buf, buflen, msg);
447   }
448 #endif
449
450   {
451     int ret;
452     int saved_errno = errno;
453
454 #if USE_XPG_STRERROR_R
455
456     {
457       extern int __xpg_strerror_r (int errnum, char *buf, size_t buflen);
458
459       ret = __xpg_strerror_r (errnum, buf, buflen);
460       if (ret < 0)
461         ret = errno;
462       if (!*buf)
463         {
464           /* glibc 2.13 would not touch buf on err, so we have to fall
465              back to GNU strerror_r which always returns a thread-safe
466              untruncated string to (partially) copy into our buf.  */
467           safe_copy (buf, buflen, strerror_r (errnum, buf, buflen));
468         }
469     }
470
471 #elif USE_SYSTEM_STRERROR_R
472
473     if (buflen > INT_MAX)
474       buflen = INT_MAX;
475
476 # ifdef __hpux
477     /* On HP-UX 11.31, strerror_r always fails when buflen < 80; it
478        also fails to change buf on EINVAL.  */
479     {
480       char stackbuf[80];
481
482       if (buflen < sizeof stackbuf)
483         {
484           ret = strerror_r (errnum, stackbuf, sizeof stackbuf);
485           if (ret == 0)
486             ret = safe_copy (buf, buflen, stackbuf);
487         }
488       else
489         ret = strerror_r (errnum, buf, buflen);
490     }
491 # else
492     /* Solaris 10 does not populate buf on ERANGE.  */
493     ret = strerror_r (errnum, buf, buflen);
494     if (ret == ERANGE && !*buf)
495       {
496         char stackbuf[STACKBUF_LEN];
497
498         /* strerror-impl.h is also affected if our choice of stackbuf
499            size is not large enough.  */
500         if (strerror_r (errnum, stackbuf, sizeof stackbuf) == ERANGE)
501           abort ();
502         safe_copy (buf, buflen, stackbuf);
503       }
504 # endif
505
506 # ifdef _AIX
507     /* AIX returns 0 rather than ERANGE when truncating strings; try
508        again until we are sure we got the entire string.  */
509     if (!ret && strlen (buf) == buflen - 1)
510       {
511         char stackbuf[STACKBUF_LEN];
512         size_t len;
513         strerror_r (errnum, stackbuf, sizeof stackbuf);
514         len = strlen (stackbuf);
515         /* stackbuf should have been large enough.  */
516         if (len + 1 == sizeof stackbuf)
517           abort ();
518         if (buflen <= len)
519           ret = ERANGE;
520       }
521 # endif
522
523     /* Some old implementations may return (-1, EINVAL) instead of EINVAL.  */
524     if (ret < 0)
525       ret = errno;
526
527     /* FreeBSD rejects 0; see http://austingroupbugs.net/view.php?id=382.  */
528     if (errnum == 0 && ret == EINVAL)
529       ret = safe_copy (buf, buflen, "Success");
530
531 #else /* USE_SYSTEM_STRERROR */
532
533     /* Try to do what strerror (errnum) does, but without clobbering the
534        buffer used by strerror().  */
535
536 # if defined __NetBSD__ || defined __hpux || ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __CYGWIN__ /* NetBSD, HP-UX, native Win32, Cygwin */
537
538     /* NetBSD:        sys_nerr, sys_errlist are declared through _NETBSD_SOURCE
539                       and <errno.h> above.
540        HP-UX:         sys_nerr, sys_errlist are declared explicitly above.
541        native Win32:  sys_nerr, sys_errlist are declared in <stdlib.h>.
542        Cygwin:        sys_nerr, sys_errlist are declared in <errno.h>.  */
543     if (errnum >= 0 && errnum < sys_nerr)
544       {
545 #  if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux)
546 #   if defined __NetBSD__
547         nl_catd catd = catopen ("libc", NL_CAT_LOCALE);
548         const char *errmsg =
549           (catd != (nl_catd)-1
550            ? catgets (catd, 1, errnum, sys_errlist[errnum])
551            : sys_errlist[errnum]);
552 #   endif
553 #   if defined __hpux
554         nl_catd catd = catopen ("perror", NL_CAT_LOCALE);
555         const char *errmsg =
556           (catd != (nl_catd)-1
557            ? catgets (catd, 1, 1 + errnum, sys_errlist[errnum])
558            : sys_errlist[errnum]);
559 #   endif
560 #  else
561         const char *errmsg = sys_errlist[errnum];
562 #  endif
563         if (errmsg == NULL || *errmsg == '\0')
564           ret = EINVAL;
565         else
566           ret = safe_copy (buf, buflen, errmsg);
567 #  if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux)
568         if (catd != (nl_catd)-1)
569           catclose (catd);
570 #  endif
571       }
572     else
573       ret = EINVAL;
574
575 # elif defined __sgi || (defined __sun && !defined _LP64) /* IRIX, Solaris <= 9 32-bit */
576
577     /* For a valid error number, the system's strerror() function returns
578        a pointer to a not copied string, not to a buffer.  */
579     if (errnum >= 0 && errnum < sys_nerr)
580       {
581         char *errmsg = strerror (errnum);
582
583         if (errmsg == NULL || *errmsg == '\0')
584           ret = EINVAL;
585         else
586           ret = safe_copy (buf, buflen, errmsg);
587       }
588     else
589       ret = EINVAL;
590
591 # else
592
593     gl_lock_lock (strerror_lock);
594
595     {
596       char *errmsg = strerror (errnum);
597
598       /* For invalid error numbers, strerror() on
599            - IRIX 6.5 returns NULL,
600            - HP-UX 11 returns an empty string.  */
601       if (errmsg == NULL || *errmsg == '\0')
602         ret = EINVAL;
603       else
604         ret = safe_copy (buf, buflen, errmsg);
605     }
606
607     gl_lock_unlock (strerror_lock);
608
609 # endif
610
611 #endif
612
613     if (ret == EINVAL && !*buf)
614       snprintf (buf, buflen, "Unknown error %d", errnum);
615
616     errno = saved_errno;
617     return ret;
618   }
619 }