]>
Commit | Line | Data |
---|---|---|
7e4afad5 | 1 | /* Copyright (C) 1991,93,95,96,97,98,2000,2002,2006,2011 |
4259230f | 2 | Free Software Foundation, Inc. |
b6ab06ce UD |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library 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 GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; if not, write to the Free | |
17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
18 | 02111-1307 USA. */ | |
19 | ||
20 | #include <libintl.h> | |
7e4afad5 | 21 | #include <stdbool.h> |
b6ab06ce | 22 | #include <stdio.h> |
7e4afad5 | 23 | #include <stdlib.h> |
b6ab06ce UD |
24 | #include <string.h> |
25 | #include <sys/param.h> | |
26 | #include <stdio-common/_itoa.h> | |
27 | ||
28 | /* It is critical here that we always use the `dcgettext' function for | |
29 | the message translation. Since <libintl.h> only defines the macro | |
30 | `dgettext' to use `dcgettext' for optimizing programs this is not | |
31 | always guaranteed. */ | |
32 | #ifndef dgettext | |
33 | # include <locale.h> /* We need LC_MESSAGES. */ | |
34 | # define dgettext(domainname, msgid) dcgettext (domainname, msgid, LC_MESSAGES) | |
35 | #endif | |
36 | ||
37 | /* Return a string describing the errno code in ERRNUM. */ | |
38 | char * | |
39 | __strerror_r (int errnum, char *buf, size_t buflen) | |
40 | { | |
4259230f UD |
41 | if (__builtin_expect (errnum < 0 || errnum >= _sys_nerr_internal |
42 | || _sys_errlist_internal[errnum] == NULL, 0)) | |
b6ab06ce UD |
43 | { |
44 | /* Buffer we use to print the number in. For a maximum size for | |
45 | `int' of 8 bytes we never need more than 20 digits. */ | |
46 | char numbuf[21]; | |
47 | const char *unk = _("Unknown error "); | |
7e4afad5 | 48 | size_t unklen = strlen (unk); |
b6ab06ce | 49 | char *p, *q; |
7e4afad5 | 50 | bool negative = errnum < 0; |
b6ab06ce UD |
51 | |
52 | numbuf[20] = '\0'; | |
7e4afad5 | 53 | p = _itoa_word (abs (errnum), &numbuf[20], 10, 0); |
b6ab06ce UD |
54 | |
55 | /* Now construct the result while taking care for the destination | |
56 | buffer size. */ | |
57 | q = __mempcpy (buf, unk, MIN (unklen, buflen)); | |
7e4afad5 UD |
58 | if (negative && unklen < buflen) |
59 | { | |
60 | *q++ = '-'; | |
61 | ++unklen; | |
62 | } | |
b6ab06ce UD |
63 | if (unklen < buflen) |
64 | memcpy (q, p, MIN ((size_t) (&numbuf[21] - p), buflen - unklen)); | |
65 | ||
66 | /* Terminate the string in any case. */ | |
67 | if (buflen > 0) | |
68 | buf[buflen - 1] = '\0'; | |
69 | ||
70 | return buf; | |
71 | } | |
72 | ||
73 | return (char *) _(_sys_errlist_internal[errnum]); | |
74 | } | |
75 | weak_alias (__strerror_r, strerror_r) | |
76 | libc_hidden_def (__strerror_r) |