Diffstat (limited to 'pwmanager/libcrypt/error/strerror.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | pwmanager/libcrypt/error/strerror.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/pwmanager/libcrypt/error/strerror.c b/pwmanager/libcrypt/error/strerror.c new file mode 100644 index 0000000..410c4ab --- a/dev/null +++ b/pwmanager/libcrypt/error/strerror.c | |||
@@ -0,0 +1,169 @@ | |||
1 | /* strerror.c - Describing an error code. | ||
2 | Copyright (C) 2003 g10 Code GmbH | ||
3 | |||
4 | This file is part of libgpg-error. | ||
5 | |||
6 | libgpg-error is free software; you can redistribute it and/or | ||
7 | modify it under the terms of the GNU Lesser General Public License | ||
8 | as published by the Free Software Foundation; either version 2.1 of | ||
9 | the License, or (at your option) any later version. | ||
10 | |||
11 | libgpg-error is distributed in the hope that it will be useful, but | ||
12 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | Lesser General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU Lesser General Public | ||
17 | License along with libgpg-error; if not, write to the Free | ||
18 | Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
19 | 02111-1307, USA. */ | ||
20 | |||
21 | #if HAVE_CONFIG_H | ||
22 | #include <config.h> | ||
23 | #endif | ||
24 | |||
25 | #include <stdlib.h> | ||
26 | #include <stdio.h> | ||
27 | #include <string.h> | ||
28 | #include <errno.h> | ||
29 | |||
30 | #include <gpg-error.h> | ||
31 | |||
32 | #include "gettext.h" | ||
33 | #include "err-codes.h" | ||
34 | |||
35 | /* Return a pointer to a string containing a description of the error | ||
36 | code in the error value ERR. This function is not thread-safe. */ | ||
37 | const char * | ||
38 | gpg_strerror (gpg_error_t err) | ||
39 | { | ||
40 | gpg_err_code_t code = gpg_err_code (err); | ||
41 | |||
42 | if (code & GPG_ERR_SYSTEM_ERROR) | ||
43 | { | ||
44 | int no = gpg_err_code_to_errno (code); | ||
45 | if (no) | ||
46 | return strerror (no); | ||
47 | else | ||
48 | code = GPG_ERR_UNKNOWN_ERRNO; | ||
49 | } | ||
50 | return dgettext (PACKAGE, msgstr + msgidx[msgidxof (code)]); | ||
51 | } | ||
52 | |||
53 | |||
54 | #ifdef HAVE_STRERROR_R | ||
55 | #ifdef STRERROR_R_CHAR_P | ||
56 | /* The GNU C library and probably some other systems have this weird | ||
57 | variant of strerror_r. */ | ||
58 | |||
59 | /* Return a dynamically allocated string in *STR describing the system | ||
60 | error NO. If this call succeeds, return 1. If this call fails due | ||
61 | to a resource shortage, set *STR to NULL and return 1. If this | ||
62 | call fails because the error number is not valid, don't set *STR | ||
63 | and return 0. */ | ||
64 | int | ||
65 | system_strerror_r (int no, char *buf, size_t buflen) | ||
66 | { | ||
67 | char *errstr; | ||
68 | |||
69 | errstr = strerror_r (no, buf, buflen); | ||
70 | if (errstr != buf) | ||
71 | { | ||
72 | size_t errstr_len = strlen (errstr) + 1; | ||
73 | size_t cpy_len = errstr_len < buflen ? errstr_len : buflen; | ||
74 | memcpy (buf, errstr, cpy_len); | ||
75 | |||
76 | return cpy_len == errstr_len ? 0 : ERANGE; | ||
77 | } | ||
78 | else | ||
79 | { | ||
80 | /* We can not tell if the buffer was large enough, but we can | ||
81 | try to make a guess. */ | ||
82 | if (strlen (buf) + 1 >= buflen) | ||
83 | return ERANGE; | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | #else/* STRERROR_R_CHAR_P */ | ||
90 | /* Now the POSIX version. */ | ||
91 | |||
92 | int | ||
93 | system_strerror_r (int no, char *buf, size_t buflen) | ||
94 | { | ||
95 | return strerror_r (no, buf, buflen); | ||
96 | } | ||
97 | |||
98 | #endif/* STRERROR_R_CHAR_P */ | ||
99 | |||
100 | #else/* HAVE_STRERROR_H */ | ||
101 | /* Without strerror_r(), we can still provide a non-thread-safe | ||
102 | version. Maybe we are even lucky and the system's strerror() is | ||
103 | already thread-safe. */ | ||
104 | |||
105 | int | ||
106 | system_strerror_r (int no, char *buf, size_t buflen) | ||
107 | { | ||
108 | char *errstr = strerror (no); | ||
109 | |||
110 | if (!errstr) | ||
111 | { | ||
112 | int saved_errno = errno; | ||
113 | |||
114 | if (saved_errno != EINVAL) | ||
115 | snprintf (buf, buflen, "strerror failed: %i\n", errno); | ||
116 | return saved_errno; | ||
117 | } | ||
118 | else | ||
119 | { | ||
120 | size_t errstr_len = strlen (errstr) + 1; | ||
121 | size_t cpy_len = errstr_len < buflen ? errstr_len : buflen; | ||
122 | memcpy (buf, errstr, cpy_len); | ||
123 | return cpy_len == errstr_len ? 0 : ERANGE; | ||
124 | } | ||
125 | } | ||
126 | #endif | ||
127 | |||
128 | |||
129 | /* Return the error string for ERR in the user-supplied buffer BUF of | ||
130 | size BUFLEN. This function is, in contrast to gpg_strerror, | ||
131 | thread-safe if a thread-safe strerror_r() function is provided by | ||
132 | the system. If the function succeeds, 0 is returned and BUF | ||
133 | contains the string describing the error. If the buffer was not | ||
134 | large enough, ERANGE is returned and BUF contains as much of the | ||
135 | beginning of the error string as fits into the buffer. */ | ||
136 | int | ||
137 | gpg_strerror_r (gpg_error_t err, char *buf, size_t buflen) | ||
138 | { | ||
139 | gpg_err_code_t code = gpg_err_code (err); | ||
140 | const char *errstr; | ||
141 | size_t errstr_len; | ||
142 | size_t cpy_len; | ||
143 | |||
144 | if (code & GPG_ERR_SYSTEM_ERROR) | ||
145 | { | ||
146 | int no = gpg_err_code_to_errno (code); | ||
147 | if (no) | ||
148 | { | ||
149 | int system_err = system_strerror_r (no, buf, buflen); | ||
150 | |||
151 | if (system_err != EINVAL) | ||
152 | { | ||
153 | if (buflen) | ||
154 | buf[buflen - 1] = '\0'; | ||
155 | return system_err; | ||
156 | } | ||
157 | } | ||
158 | code = GPG_ERR_UNKNOWN_ERRNO; | ||
159 | } | ||
160 | |||
161 | errstr = dgettext (PACKAGE, msgstr + msgidx[msgidxof (code)]); | ||
162 | errstr_len = strlen (errstr) + 1; | ||
163 | cpy_len = errstr_len < buflen ? errstr_len : buflen; | ||
164 | memcpy (buf, errstr, cpy_len); | ||
165 | if (buflen) | ||
166 | buf[buflen - 1] = '\0'; | ||
167 | |||
168 | return cpy_len == errstr_len ? 0 : ERANGE; | ||
169 | } | ||