1 | /* Test of strerror_r() function.
|
---|
2 | Copyright (C) 2007-2021 Free Software Foundation, Inc.
|
---|
3 |
|
---|
4 | This program is free software; you can redistribute it and/or modify
|
---|
5 | it under the terms of the GNU General Public License as published by
|
---|
6 | the Free Software Foundation; either version 3, or (at your option)
|
---|
7 | any later version.
|
---|
8 |
|
---|
9 | This program is distributed in the hope that it will be useful,
|
---|
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
12 | GNU General Public License for more details.
|
---|
13 |
|
---|
14 | You should have received a copy of the GNU General Public License
|
---|
15 | along with this program; if not, see <https://www.gnu.org/licenses/>. */
|
---|
16 |
|
---|
17 | #include <config.h>
|
---|
18 |
|
---|
19 | #include <string.h>
|
---|
20 |
|
---|
21 | #include "signature.h"
|
---|
22 | SIGNATURE_CHECK (strerror_r, int, (int, char *, size_t));
|
---|
23 |
|
---|
24 | #include <errno.h>
|
---|
25 |
|
---|
26 | #include "macros.h"
|
---|
27 |
|
---|
28 | int
|
---|
29 | main (void)
|
---|
30 | {
|
---|
31 | char buf[100];
|
---|
32 | int ret;
|
---|
33 |
|
---|
34 | /* Test results with valid errnum and enough room. */
|
---|
35 |
|
---|
36 | errno = 0;
|
---|
37 | buf[0] = '\0';
|
---|
38 | ASSERT (strerror_r (EACCES, buf, sizeof buf) == 0);
|
---|
39 | ASSERT (buf[0] != '\0');
|
---|
40 | ASSERT (errno == 0);
|
---|
41 | ASSERT (strlen (buf) < sizeof buf);
|
---|
42 |
|
---|
43 | errno = 0;
|
---|
44 | buf[0] = '\0';
|
---|
45 | ASSERT (strerror_r (ETIMEDOUT, buf, sizeof buf) == 0);
|
---|
46 | ASSERT (buf[0] != '\0');
|
---|
47 | ASSERT (errno == 0);
|
---|
48 | ASSERT (strlen (buf) < sizeof buf);
|
---|
49 |
|
---|
50 | errno = 0;
|
---|
51 | buf[0] = '\0';
|
---|
52 | ASSERT (strerror_r (EOVERFLOW, buf, sizeof buf) == 0);
|
---|
53 | ASSERT (buf[0] != '\0');
|
---|
54 | ASSERT (errno == 0);
|
---|
55 | ASSERT (strlen (buf) < sizeof buf);
|
---|
56 |
|
---|
57 | /* POSIX requires strerror (0) to succeed. Reject use of "Unknown
|
---|
58 | error", but allow "Success", "No error", or even Solaris' "Error
|
---|
59 | 0" which are distinct patterns from true out-of-range strings.
|
---|
60 | http://austingroupbugs.net/view.php?id=382 */
|
---|
61 | errno = 0;
|
---|
62 | buf[0] = '\0';
|
---|
63 | ret = strerror_r (0, buf, sizeof buf);
|
---|
64 | ASSERT (ret == 0);
|
---|
65 | ASSERT (buf[0]);
|
---|
66 | ASSERT (errno == 0);
|
---|
67 | ASSERT (strstr (buf, "nknown") == NULL);
|
---|
68 | ASSERT (strstr (buf, "ndefined") == NULL);
|
---|
69 |
|
---|
70 | /* Test results with out-of-range errnum and enough room. POSIX
|
---|
71 | allows an empty string on success, and allows an unchanged buf on
|
---|
72 | error, but these are not useful, so we guarantee contents. */
|
---|
73 | errno = 0;
|
---|
74 | buf[0] = '^';
|
---|
75 | ret = strerror_r (-3, buf, sizeof buf);
|
---|
76 | ASSERT (ret == 0 || ret == EINVAL);
|
---|
77 | ASSERT (buf[0] != '^');
|
---|
78 | ASSERT (*buf);
|
---|
79 | ASSERT (errno == 0);
|
---|
80 | ASSERT (strlen (buf) < sizeof buf);
|
---|
81 |
|
---|
82 | /* Test results with a too small buffer. POSIX requires an error;
|
---|
83 | only ERANGE for 0 and valid errors, and a choice of ERANGE or
|
---|
84 | EINVAL for out-of-range values. On error, POSIX permits buf to
|
---|
85 | be empty, unchanged, or unterminated, but these are not useful,
|
---|
86 | so we guarantee NUL-terminated truncated contents for all but
|
---|
87 | size 0. http://austingroupbugs.net/view.php?id=398. Also ensure
|
---|
88 | that no out-of-bounds writes occur. */
|
---|
89 | {
|
---|
90 | int errs[] = { EACCES, 0, -3, };
|
---|
91 | int j;
|
---|
92 |
|
---|
93 | buf[sizeof buf - 1] = '\0';
|
---|
94 | for (j = 0; j < SIZEOF (errs); j++)
|
---|
95 | {
|
---|
96 | int err = errs[j];
|
---|
97 | char buf2[sizeof buf] = "";
|
---|
98 | size_t len;
|
---|
99 | size_t i;
|
---|
100 |
|
---|
101 | strerror_r (err, buf2, sizeof buf2);
|
---|
102 | len = strlen (buf2);
|
---|
103 | ASSERT (len < sizeof buf);
|
---|
104 |
|
---|
105 | for (i = 0; i <= len; i++)
|
---|
106 | {
|
---|
107 | memset (buf, '^', sizeof buf - 1);
|
---|
108 | errno = 0;
|
---|
109 | ret = strerror_r (err, buf, i);
|
---|
110 | ASSERT (errno == 0);
|
---|
111 | if (j == 2)
|
---|
112 | ASSERT (ret == ERANGE || ret == EINVAL);
|
---|
113 | else
|
---|
114 | ASSERT (ret == ERANGE);
|
---|
115 | if (i)
|
---|
116 | {
|
---|
117 | ASSERT (strncmp (buf, buf2, i - 1) == 0);
|
---|
118 | ASSERT (buf[i - 1] == '\0');
|
---|
119 | }
|
---|
120 | ASSERT (strspn (buf + i, "^") == sizeof buf - 1 - i);
|
---|
121 | }
|
---|
122 |
|
---|
123 | strcpy (buf, "BADFACE");
|
---|
124 | errno = 0;
|
---|
125 | ret = strerror_r (err, buf, len + 1);
|
---|
126 | ASSERT (ret != ERANGE);
|
---|
127 | ASSERT (errno == 0);
|
---|
128 | ASSERT (strcmp (buf, buf2) == 0);
|
---|
129 | }
|
---|
130 | }
|
---|
131 |
|
---|
132 | #if GNULIB_STRERROR
|
---|
133 | /* Test that strerror_r does not clobber strerror buffer. On some
|
---|
134 | platforms, this test can only succeed if gnulib also replaces
|
---|
135 | strerror. */
|
---|
136 | {
|
---|
137 | const char *msg1;
|
---|
138 | const char *msg2;
|
---|
139 | const char *msg3;
|
---|
140 | const char *msg4;
|
---|
141 | char *str1;
|
---|
142 | char *str2;
|
---|
143 | char *str3;
|
---|
144 | char *str4;
|
---|
145 |
|
---|
146 | msg1 = strerror (ENOENT);
|
---|
147 | ASSERT (msg1);
|
---|
148 | str1 = strdup (msg1);
|
---|
149 | ASSERT (str1);
|
---|
150 |
|
---|
151 | msg2 = strerror (ERANGE);
|
---|
152 | ASSERT (msg2);
|
---|
153 | str2 = strdup (msg2);
|
---|
154 | ASSERT (str2);
|
---|
155 |
|
---|
156 | msg3 = strerror (-4);
|
---|
157 | ASSERT (msg3);
|
---|
158 | str3 = strdup (msg3);
|
---|
159 | ASSERT (str3);
|
---|
160 |
|
---|
161 | msg4 = strerror (1729576);
|
---|
162 | ASSERT (msg4);
|
---|
163 | str4 = strdup (msg4);
|
---|
164 | ASSERT (str4);
|
---|
165 |
|
---|
166 | strerror_r (EACCES, buf, sizeof buf);
|
---|
167 | strerror_r (-5, buf, sizeof buf);
|
---|
168 | ASSERT (STREQ (msg4, str4));
|
---|
169 |
|
---|
170 | free (str1);
|
---|
171 | free (str2);
|
---|
172 | free (str3);
|
---|
173 | free (str4);
|
---|
174 | }
|
---|
175 | #endif
|
---|
176 |
|
---|
177 | return 0;
|
---|
178 | }
|
---|