summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'src/regress/lib/libc')
-rw-r--r--src/regress/lib/libc/Makefile11
-rw-r--r--src/regress/lib/libc/arc4random-fork/arc4random-fork.c2
-rw-r--r--src/regress/lib/libc/explicit_bzero/explicit_bzero.c4
-rw-r--r--src/regress/lib/libc/hash/Makefile5
-rw-r--r--src/regress/lib/libc/hash/hash_test.c935
-rw-r--r--src/regress/lib/libc/illumos/Makefile7
-rw-r--r--src/regress/lib/libc/illumos/Makefile.inc9
-rw-r--r--src/regress/lib/libc/illumos/oclo/Makefile16
-rw-r--r--src/regress/lib/libc/malloc/malloc_errs/malloc_errs.c15
-rw-r--r--src/regress/lib/libc/malloc/malloc_ulimit1/malloc_ulimit1.c4
-rw-r--r--src/regress/lib/libc/stdio/Makefile29
-rw-r--r--src/regress/lib/libc/stdio/test___fpending.c58
-rw-r--r--src/regress/lib/libc/stdio/test___freadahead.c71
-rw-r--r--src/regress/lib/libc/stdio/test___freading.c125
-rw-r--r--src/regress/lib/libc/stdio/test___freadptr.c78
-rw-r--r--src/regress/lib/libc/stdio/test___fseterr.c60
-rw-r--r--src/regress/lib/libc/stdio/test___fwriting.c83
-rw-r--r--src/regress/lib/libc/stdio/test_fflush.c345
-rw-r--r--src/regress/lib/libc/stdio/test_ungetwc.c90
19 files changed, 1931 insertions, 16 deletions
diff --git a/src/regress/lib/libc/Makefile b/src/regress/lib/libc/Makefile
index 3cd970e49d..7a8db225ef 100644
--- a/src/regress/lib/libc/Makefile
+++ b/src/regress/lib/libc/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.59 2024/07/14 09:48:48 jca Exp $ 1# $OpenBSD: Makefile,v 1.62 2025/08/04 06:10:40 tb Exp $
2 2
3SUBDIR+= _setjmp 3SUBDIR+= _setjmp
4SUBDIR+= alloca arc4random-fork atexit 4SUBDIR+= alloca arc4random-fork atexit
@@ -9,8 +9,9 @@ SUBDIR+= elf_aux_info
9SUBDIR+= env explicit_bzero 9SUBDIR+= env explicit_bzero
10SUBDIR+= ffs fmemopen fnmatch fpclassify fread 10SUBDIR+= ffs fmemopen fnmatch fpclassify fread
11SUBDIR+= gcvt getaddrinfo getcap getopt getopt_long glob 11SUBDIR+= gcvt getaddrinfo getcap getopt getopt_long glob
12SUBDIR+= hash
12SUBDIR+= hsearch 13SUBDIR+= hsearch
13SUBDIR+= ieeefp ifnameindex 14SUBDIR+= ieeefp ifnameindex illumos
14SUBDIR+= ldexp locale longjmp 15SUBDIR+= ldexp locale longjmp
15SUBDIR+= malloc mkstemp modf 16SUBDIR+= malloc mkstemp modf
16SUBDIR+= netdb 17SUBDIR+= netdb
@@ -18,9 +19,9 @@ SUBDIR+= open_memstream orientation
18SUBDIR+= popen printf 19SUBDIR+= popen printf
19SUBDIR+= qsort 20SUBDIR+= qsort
20SUBDIR+= regex 21SUBDIR+= regex
21SUBDIR+= setjmp setjmp-signal sigsetjmp sigthr sleep sprintf stdio_threading 22SUBDIR+= setjmp setjmp-signal sigsetjmp sigthr sleep sprintf stdio
22SUBDIR+= stpncpy strchr strerror strlcat strlcpy strnlen strtod strtol strtonum 23SUBDIR+= stdio_threading stpncpy strchr strerror strlcat strlcpy strnlen
23SUBDIR+= sys 24SUBDIR+= strtod strtol strtonum sys
24SUBDIR+= telldir time timingsafe 25SUBDIR+= telldir time timingsafe
25SUBDIR+= uuid 26SUBDIR+= uuid
26SUBDIR+= vis 27SUBDIR+= vis
diff --git a/src/regress/lib/libc/arc4random-fork/arc4random-fork.c b/src/regress/lib/libc/arc4random-fork/arc4random-fork.c
index 4bc9c634f1..9b334945af 100644
--- a/src/regress/lib/libc/arc4random-fork/arc4random-fork.c
+++ b/src/regress/lib/libc/arc4random-fork/arc4random-fork.c
@@ -111,7 +111,7 @@ main(int argc, char *argv[])
111 } 111 }
112 112
113 if (flagprefork) 113 if (flagprefork)
114 arc4random(); 114 (void)arc4random();
115 115
116 bufparent = mmap(NULL, sizeof(Buf), PROT_READ|PROT_WRITE, 116 bufparent = mmap(NULL, sizeof(Buf), PROT_READ|PROT_WRITE,
117 MAP_ANON|MAP_PRIVATE, -1, 0); 117 MAP_ANON|MAP_PRIVATE, -1, 0);
diff --git a/src/regress/lib/libc/explicit_bzero/explicit_bzero.c b/src/regress/lib/libc/explicit_bzero/explicit_bzero.c
index 496bafb208..30c86290e8 100644
--- a/src/regress/lib/libc/explicit_bzero/explicit_bzero.c
+++ b/src/regress/lib/libc/explicit_bzero/explicit_bzero.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: explicit_bzero.c,v 1.9 2022/02/10 08:39:32 tb Exp $ */ 1/* $OpenBSD: explicit_bzero.c,v 1.10 2025/05/31 15:31:40 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Google Inc. 3 * Copyright (c) 2014 Google Inc.
4 * 4 *
@@ -28,9 +28,11 @@
28 28
29#if defined(__has_feature) 29#if defined(__has_feature)
30#if __has_feature(address_sanitizer) 30#if __has_feature(address_sanitizer)
31#ifndef __SANITIZE_ADDRESS__
31#define __SANITIZE_ADDRESS__ 32#define __SANITIZE_ADDRESS__
32#endif 33#endif
33#endif 34#endif
35#endif
34#ifdef __SANITIZE_ADDRESS__ 36#ifdef __SANITIZE_ADDRESS__
35#define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) 37#define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
36#else 38#else
diff --git a/src/regress/lib/libc/hash/Makefile b/src/regress/lib/libc/hash/Makefile
new file mode 100644
index 0000000000..9bd69bf8df
--- /dev/null
+++ b/src/regress/lib/libc/hash/Makefile
@@ -0,0 +1,5 @@
1# $OpenBSD: Makefile,v 1.2 2025/04/14 18:33:56 tb Exp $
2
3PROG = hash_test
4
5.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/hash/hash_test.c b/src/regress/lib/libc/hash/hash_test.c
new file mode 100644
index 0000000000..c04a0458fe
--- /dev/null
+++ b/src/regress/lib/libc/hash/hash_test.c
@@ -0,0 +1,935 @@
1/* $OpenBSD: hash_test.c,v 1.3 2025/08/02 06:05:13 tb Exp $ */
2
3/*
4 * Copyright (c) 2025 Theo Buehler <tb@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20
21#include <md5.h>
22#include <rmd160.h>
23#include <sha1.h>
24#include <sha2.h>
25#include <stdio.h>
26#include <string.h>
27
28#define MAX_DIGEST_LENGTH SHA512_DIGEST_LENGTH
29
30struct hash_test_case {
31 const char *in;
32 const uint8_t out[MAX_DIGEST_LENGTH];
33};
34
35enum {
36 hash_md5,
37 hash_rmd160,
38 hash_sha1,
39 hash_sha224,
40 hash_sha256,
41 hash_sha384,
42 hash_sha512,
43 hash_sha512_256,
44 NUM_HASHES,
45};
46
47/* RFC 1321, Appendix A.5 */
48static const struct hash_test_case md5_tests[] = {
49 {
50 .out = {
51 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
52 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e,
53 },
54 },
55 {
56 .in = "",
57 .out = {
58 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
59 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e,
60 },
61 },
62 {
63 .in = "a",
64 .out = {
65 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
66 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61,
67 },
68 },
69 {
70 .in = "abc",
71 .out = {
72 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
73 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72,
74 },
75 },
76 {
77 .in = "message digest",
78 .out = {
79 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
80 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0,
81 },
82 },
83 {
84 .in = "abcdefghijklmnopqrstuvwxyz",
85 .out = {
86 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
87 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b,
88 },
89 },
90 {
91 .in = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
92 "abcdefghijklmnopqrstuvwxyz0123456789",
93 .out = {
94 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
95 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f,
96 },
97 },
98 {
99 .in = "1234567890123456789012345678901234567890"
100 "1234567890123456789012345678901234567890",
101 .out = {
102 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
103 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a,
104 },
105 },
106};
107
108#define N_MD5_TESTS (sizeof(md5_tests) / sizeof(md5_tests[0]))
109
110static void
111md5_init(void *ctx)
112{
113 MD5Init(ctx);
114}
115
116static void
117md5_update(void *ctx, const uint8_t *data, size_t len)
118{
119 MD5Update(ctx, data, len);
120}
121
122static void
123md5_final(void *digest, void *ctx)
124{
125 MD5Final(digest, ctx);
126}
127
128/* https://homes.esat.kuleuven.be/~bosselae/ripemd160.html */
129static const struct hash_test_case rmd160_tests[] = {
130 {
131 .out = {
132 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54,
133 0x61, 0x28, 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48,
134 0xb2, 0x25, 0x8d, 0x31,
135 },
136 },
137 {
138 .in = "",
139 .out = {
140 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54,
141 0x61, 0x28, 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48,
142 0xb2, 0x25, 0x8d, 0x31,
143 },
144 },
145 {
146 .in = "a",
147 .out = {
148 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9,
149 0xda, 0xae, 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83,
150 0x5a, 0x46, 0x7f, 0xfe,
151 },
152 },
153 {
154 .in = "abc",
155 .out = {
156 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a,
157 0x9b, 0x04, 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87,
158 0xf1, 0x5a, 0x0b, 0xfc,
159 },
160 },
161 {
162 .in = "message digest",
163 .out = {
164 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5,
165 0x72, 0xb8, 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa,
166 0x21, 0x59, 0x5f, 0x36,
167 },
168 },
169 {
170 .in = "abcdefghijklmnopqrstuvwxyz",
171 .out = {
172 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b,
173 0x56, 0xbb, 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65,
174 0xb3, 0x70, 0x8d, 0xbc,
175 },
176 },
177 {
178 .in = "abcdbcdecdefdefgefghfghighijhijkijkljkl"
179 "mklmnlmnomnopnopq",
180 .out = {
181 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88,
182 0xe4, 0x05, 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a,
183 0xda, 0x62, 0xeb, 0x2b,
184 },
185 },
186 {
187 .in = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
188 "0123456789",
189 .out = {
190 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02,
191 0x86, 0xed, 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79,
192 0xb2, 0x1f, 0x51, 0x89,
193 },
194 },
195 {
196 .in = "1234567890123456789012345678901234567890"
197 "1234567890123456789012345678901234567890",
198 .out = {
199 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39,
200 0xf4, 0xdb, 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf,
201 0x63, 0x32, 0x6b, 0xfb,
202 },
203 },
204};
205
206#define N_RMD160_TESTS (sizeof(rmd160_tests) / sizeof(rmd160_tests[0]))
207
208static void
209rmd160_init(void *ctx)
210{
211 RMD160Init(ctx);
212}
213
214static void
215rmd160_update(void *ctx, const uint8_t *data, size_t len)
216{
217 RMD160Update(ctx, data, len);
218}
219
220static void
221rmd160_final(void *digest, void *ctx)
222{
223 RMD160Final(digest, ctx);
224}
225
226/* RFC 3174 - Appendix A (plus two zero-length tests) */
227static const struct hash_test_case sha1_tests[] = {
228 {
229 .out = {
230 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d,
231 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90,
232 0xaf, 0xd8, 0x07, 0x09,
233 },
234 },
235 {
236 .in = "",
237 .out = {
238 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d,
239 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90,
240 0xaf, 0xd8, 0x07, 0x09,
241 },
242 },
243 {
244 .in = "abc",
245 .out = {
246 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
247 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
248 0x9c, 0xd0, 0xd8, 0x9d,
249 },
250 },
251 {
252 .in = "abcdbcdecdefdefgefghfghighijhi"
253 "jkijkljklmklmnlmnomnopnopq",
254 .out = {
255 0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e,
256 0xba, 0xae, 0x4a, 0xa1, 0xf9, 0x51, 0x29, 0xe5,
257 0xe5, 0x46, 0x70, 0xf1,
258 },
259 },
260 {
261 .in = "0123456701234567012345670123456701234567012345670123456701234567"
262 "0123456701234567012345670123456701234567012345670123456701234567"
263 "0123456701234567012345670123456701234567012345670123456701234567"
264 "0123456701234567012345670123456701234567012345670123456701234567"
265 "0123456701234567012345670123456701234567012345670123456701234567"
266 "0123456701234567012345670123456701234567012345670123456701234567"
267 "0123456701234567012345670123456701234567012345670123456701234567"
268 "0123456701234567012345670123456701234567012345670123456701234567"
269 "0123456701234567012345670123456701234567012345670123456701234567"
270 "0123456701234567012345670123456701234567012345670123456701234567",
271 .out = {
272 0xde, 0xa3, 0x56, 0xa2, 0xcd, 0xdd, 0x90, 0xc7,
273 0xa7, 0xec, 0xed, 0xc5, 0xeb, 0xb5, 0x63, 0x93,
274 0x4f, 0x46, 0x04, 0x52,
275 },
276 },
277};
278
279#define N_SHA1_TESTS (sizeof(sha1_tests) / sizeof(sha1_tests[0]))
280
281static void
282sha1_init(void *ctx)
283{
284 SHA1Init(ctx);
285}
286
287static void
288sha1_update(void *ctx, const uint8_t *data, size_t len)
289{
290 SHA1Update(ctx, data, len);
291}
292
293static void
294sha1_final(void *digest, void *ctx)
295{
296 SHA1Final(digest, ctx);
297}
298
299static const struct hash_test_case sha224_tests[] = {
300 {
301 .out = {
302 0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9,
303 0x47, 0x61, 0x02, 0xbb, 0x28, 0x82, 0x34, 0xc4,
304 0x15, 0xa2, 0xb0, 0x1f, 0x82, 0x8e, 0xa6, 0x2a,
305 0xc5, 0xb3, 0xe4, 0x2f,
306 },
307 },
308 {
309 .in = "",
310 .out = {
311 0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9,
312 0x47, 0x61, 0x02, 0xbb, 0x28, 0x82, 0x34, 0xc4,
313 0x15, 0xa2, 0xb0, 0x1f, 0x82, 0x8e, 0xa6, 0x2a,
314 0xc5, 0xb3, 0xe4, 0x2f,
315 },
316 },
317 {
318 .in = "abc",
319 .out = {
320 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, 0x22,
321 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, 0x55, 0xb3,
322 0x2a, 0xad, 0xbc, 0xe4, 0xbd, 0xa0, 0xb3, 0xf7,
323 0xe3, 0x6c, 0x9d, 0xa7,
324 },
325 },
326 {
327 .in = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
328 .out = {
329 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, 0xcc,
330 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, 0x01, 0x50,
331 0xb0, 0xc6, 0x45, 0x5c, 0xb4, 0xf5, 0x8b, 0x19,
332 0x52, 0x52, 0x25, 0x25,
333 },
334 },
335 {
336 .in = "0123456701234567012345670123456701234567012345670123456701234567"
337 "0123456701234567012345670123456701234567012345670123456701234567"
338 "0123456701234567012345670123456701234567012345670123456701234567"
339 "0123456701234567012345670123456701234567012345670123456701234567"
340 "0123456701234567012345670123456701234567012345670123456701234567"
341 "0123456701234567012345670123456701234567012345670123456701234567"
342 "0123456701234567012345670123456701234567012345670123456701234567"
343 "0123456701234567012345670123456701234567012345670123456701234567"
344 "0123456701234567012345670123456701234567012345670123456701234567"
345 "0123456701234567012345670123456701234567012345670123456701234567",
346 .out = {
347 0x56, 0x7f, 0x69, 0xf1, 0x68, 0xcd, 0x78, 0x44,
348 0xe6, 0x52, 0x59, 0xce, 0x65, 0x8f, 0xe7, 0xaa,
349 0xdf, 0xa2, 0x52, 0x16, 0xe6, 0x8e, 0xca, 0x0e,
350 0xb7, 0xab, 0x82, 0x62,
351 },
352 },
353 {
354 .in = "\x07",
355 .out = {
356 0x00, 0xec, 0xd5, 0xf1, 0x38, 0x42, 0x2b, 0x8a,
357 0xd7, 0x4c, 0x97, 0x99, 0xfd, 0x82, 0x6c, 0x53,
358 0x1b, 0xad, 0x2f, 0xca, 0xbc, 0x74, 0x50, 0xbe,
359 0xe2, 0xaa, 0x8c, 0x2a,
360 },
361 },
362};
363
364#define N_SHA224_TESTS (sizeof(sha224_tests) / sizeof(sha224_tests[0]))
365
366static void
367sha224_init(void *ctx)
368{
369 SHA224Init(ctx);
370}
371
372static void
373sha224_update(void *ctx, const uint8_t *data, size_t len)
374{
375 SHA224Update(ctx, data, len);
376}
377
378static void
379sha224_final(void *digest, void *ctx)
380{
381 SHA224Final(digest, ctx);
382}
383
384static const struct hash_test_case sha256_tests[] = {
385 {
386 .out = {
387 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
388 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
389 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
390 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
391 },
392 },
393 {
394 .in = "",
395 .out = {
396 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
397 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
398 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
399 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
400 },
401 },
402 {
403 .in = "abc",
404 .out = {
405 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
406 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
407 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
408 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD,
409 },
410 },
411 {
412 .in = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
413 .out = {
414 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
415 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
416 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
417 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1,
418 },
419 },
420 {
421 .in = "0123456701234567012345670123456701234567012345670123456701234567"
422 "0123456701234567012345670123456701234567012345670123456701234567"
423 "0123456701234567012345670123456701234567012345670123456701234567"
424 "0123456701234567012345670123456701234567012345670123456701234567"
425 "0123456701234567012345670123456701234567012345670123456701234567"
426 "0123456701234567012345670123456701234567012345670123456701234567"
427 "0123456701234567012345670123456701234567012345670123456701234567"
428 "0123456701234567012345670123456701234567012345670123456701234567"
429 "0123456701234567012345670123456701234567012345670123456701234567"
430 "0123456701234567012345670123456701234567012345670123456701234567",
431 .out = {
432 0x59, 0x48, 0x47, 0x32, 0x84, 0x51, 0xBD, 0xFA,
433 0x85, 0x05, 0x62, 0x25, 0x46, 0x2C, 0xC1, 0xD8,
434 0x67, 0xD8, 0x77, 0xFB, 0x38, 0x8D, 0xF0, 0xCE,
435 0x35, 0xF2, 0x5A, 0xB5, 0x56, 0x2B, 0xFB, 0xB5,
436 },
437 },
438 {
439 .in = "\x19",
440 .out = {
441 0x68, 0xaa, 0x2e, 0x2e, 0xe5, 0xdf, 0xf9, 0x6e,
442 0x33, 0x55, 0xe6, 0xc7, 0xee, 0x37, 0x3e, 0x3d,
443 0x6a, 0x4e, 0x17, 0xf7, 0x5f, 0x95, 0x18, 0xd8,
444 0x43, 0x70, 0x9c, 0x0c, 0x9b, 0xc3, 0xe3, 0xd4,
445 },
446 },
447};
448
449#define N_SHA256_TESTS (sizeof(sha256_tests) / sizeof(sha256_tests[0]))
450
451static void
452sha256_init(void *ctx)
453{
454 SHA256Init(ctx);
455}
456
457static void
458sha256_update(void *ctx, const uint8_t *data, size_t len)
459{
460 SHA256Update(ctx, data, len);
461}
462
463static void
464sha256_final(void *digest, void *ctx)
465{
466 SHA256Final(digest, ctx);
467}
468
469static const struct hash_test_case sha384_tests[] = {
470 {
471 .out = {
472 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38,
473 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a,
474 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43,
475 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda,
476 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb,
477 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b,
478 },
479 },
480 {
481 .in = "",
482 .out = {
483 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38,
484 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a,
485 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43,
486 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda,
487 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb,
488 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b,
489 },
490 },
491 {
492 .in = "abc",
493 .out = {
494 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
495 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
496 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
497 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
498 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
499 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7,
500 },
501 },
502 {
503 .in = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
504 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
505 .out = {
506 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
507 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
508 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
509 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
510 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
511 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39,
512 },
513 },
514 {
515 .in = "0123456701234567012345670123456701234567012345670123456701234567"
516 "0123456701234567012345670123456701234567012345670123456701234567"
517 "0123456701234567012345670123456701234567012345670123456701234567"
518 "0123456701234567012345670123456701234567012345670123456701234567"
519 "0123456701234567012345670123456701234567012345670123456701234567"
520 "0123456701234567012345670123456701234567012345670123456701234567"
521 "0123456701234567012345670123456701234567012345670123456701234567"
522 "0123456701234567012345670123456701234567012345670123456701234567"
523 "0123456701234567012345670123456701234567012345670123456701234567"
524 "0123456701234567012345670123456701234567012345670123456701234567",
525 .out = {
526 0x2f, 0xc6, 0x4a, 0x4f, 0x50, 0x0d, 0xdb, 0x68,
527 0x28, 0xf6, 0xa3, 0x43, 0x0b, 0x8d, 0xd7, 0x2a,
528 0x36, 0x8e, 0xb7, 0xf3, 0xa8, 0x32, 0x2a, 0x70,
529 0xbc, 0x84, 0x27, 0x5b, 0x9c, 0x0b, 0x3a, 0xb0,
530 0x0d, 0x27, 0xa5, 0xcc, 0x3c, 0x2d, 0x22, 0x4a,
531 0xa6, 0xb6, 0x1a, 0x0d, 0x79, 0xfb, 0x45, 0x96,
532 },
533 },
534 {
535 .in = "\xb9",
536 .out = {
537 0xbc, 0x80, 0x89, 0xa1, 0x90, 0x07, 0xc0, 0xb1,
538 0x41, 0x95, 0xf4, 0xec, 0xc7, 0x40, 0x94, 0xfe,
539 0xc6, 0x4f, 0x01, 0xf9, 0x09, 0x29, 0x28, 0x2c,
540 0x2f, 0xb3, 0x92, 0x88, 0x15, 0x78, 0x20, 0x8a,
541 0xd4, 0x66, 0x82, 0x8b, 0x1c, 0x6c, 0x28, 0x3d,
542 0x27, 0x22, 0xcf, 0x0a, 0xd1, 0xab, 0x69, 0x38,
543 },
544 },
545};
546
547#define N_SHA384_TESTS (sizeof(sha384_tests) / sizeof(sha384_tests[0]))
548
549static void
550sha384_init(void *ctx)
551{
552 SHA384Init(ctx);
553}
554
555static void
556sha384_update(void *ctx, const uint8_t *data, size_t len)
557{
558 SHA384Update(ctx, data, len);
559}
560
561static void
562sha384_final(void *digest, void *ctx)
563{
564 SHA384Final(digest, ctx);
565}
566
567static const struct hash_test_case sha512_tests[] = {
568 {
569 .out = {
570 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
571 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
572 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
573 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
574 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
575 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
576 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
577 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e,
578 },
579 },
580 {
581 .in = "",
582 .out = {
583 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
584 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
585 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
586 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
587 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
588 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
589 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
590 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e,
591 },
592 },
593 {
594 .in = "abc",
595 .out = {
596 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
597 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
598 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
599 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
600 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
601 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
602 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
603 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f,
604 },
605 },
606 {
607 .in = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
608 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
609 .out = {
610 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
611 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
612 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
613 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
614 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
615 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
616 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
617 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09,
618 },
619 },
620 {
621 .in = "0123456701234567012345670123456701234567012345670123456701234567"
622 "0123456701234567012345670123456701234567012345670123456701234567"
623 "0123456701234567012345670123456701234567012345670123456701234567"
624 "0123456701234567012345670123456701234567012345670123456701234567"
625 "0123456701234567012345670123456701234567012345670123456701234567"
626 "0123456701234567012345670123456701234567012345670123456701234567"
627 "0123456701234567012345670123456701234567012345670123456701234567"
628 "0123456701234567012345670123456701234567012345670123456701234567"
629 "0123456701234567012345670123456701234567012345670123456701234567"
630 "0123456701234567012345670123456701234567012345670123456701234567",
631 .out = {
632 0x89, 0xd0, 0x5b, 0xa6, 0x32, 0xc6, 0x99, 0xc3,
633 0x12, 0x31, 0xde, 0xd4, 0xff, 0xc1, 0x27, 0xd5,
634 0xa8, 0x94, 0xda, 0xd4, 0x12, 0xc0, 0xe0, 0x24,
635 0xdb, 0x87, 0x2d, 0x1a, 0xbd, 0x2b, 0xa8, 0x14,
636 0x1a, 0x0f, 0x85, 0x07, 0x2a, 0x9b, 0xe1, 0xe2,
637 0xaa, 0x04, 0xcf, 0x33, 0xc7, 0x65, 0xcb, 0x51,
638 0x08, 0x13, 0xa3, 0x9c, 0xd5, 0xa8, 0x4c, 0x4a,
639 0xca, 0xa6, 0x4d, 0x3f, 0x3f, 0xb7, 0xba, 0xe9,
640 },
641 },
642 {
643 .in = "\xd0",
644 .out = {
645 0x99, 0x92, 0x20, 0x29, 0x38, 0xe8, 0x82, 0xe7,
646 0x3e, 0x20, 0xf6, 0xb6, 0x9e, 0x68, 0xa0, 0xa7,
647 0x14, 0x90, 0x90, 0x42, 0x3d, 0x93, 0xc8, 0x1b,
648 0xab, 0x3f, 0x21, 0x67, 0x8d, 0x4a, 0xce, 0xee,
649 0xe5, 0x0e, 0x4e, 0x8c, 0xaf, 0xad, 0xa4, 0xc8,
650 0x5a, 0x54, 0xea, 0x83, 0x06, 0x82, 0x6c, 0x4a,
651 0xd6, 0xe7, 0x4c, 0xec, 0xe9, 0x63, 0x1b, 0xfa,
652 0x8a, 0x54, 0x9b, 0x4a, 0xb3, 0xfb, 0xba, 0x15,
653 },
654 },
655};
656
657#define N_SHA512_TESTS (sizeof(sha512_tests) / sizeof(sha512_tests[0]))
658
659static void
660sha512_init(void *ctx)
661{
662 SHA512Init(ctx);
663}
664
665static void
666sha512_update(void *ctx, const uint8_t *data, size_t len)
667{
668 SHA512Update(ctx, data, len);
669}
670
671static void
672sha512_final(void *digest, void *ctx)
673{
674 SHA512Final(digest, ctx);
675}
676
677static const struct hash_test_case sha512_256_tests[] = {
678 {
679 .out = {
680 0xc6, 0x72, 0xb8, 0xd1, 0xef, 0x56, 0xed, 0x28,
681 0xab, 0x87, 0xc3, 0x62, 0x2c, 0x51, 0x14, 0x06,
682 0x9b, 0xdd, 0x3a, 0xd7, 0xb8, 0xf9, 0x73, 0x74,
683 0x98, 0xd0, 0xc0, 0x1e, 0xce, 0xf0, 0x96, 0x7a,
684 },
685 },
686 {
687 .in = "",
688 .out = {
689 0xc6, 0x72, 0xb8, 0xd1, 0xef, 0x56, 0xed, 0x28,
690 0xab, 0x87, 0xc3, 0x62, 0x2c, 0x51, 0x14, 0x06,
691 0x9b, 0xdd, 0x3a, 0xd7, 0xb8, 0xf9, 0x73, 0x74,
692 0x98, 0xd0, 0xc0, 0x1e, 0xce, 0xf0, 0x96, 0x7a,
693 },
694 },
695 {
696 .in = "abc",
697 .out = {
698 0x53, 0x04, 0x8e, 0x26, 0x81, 0x94, 0x1e, 0xf9,
699 0x9b, 0x2e, 0x29, 0xb7, 0x6b, 0x4c, 0x7d, 0xab,
700 0xe4, 0xc2, 0xd0, 0xc6, 0x34, 0xfc, 0x6d, 0x46,
701 0xe0, 0xe2, 0xf1, 0x31, 0x07, 0xe7, 0xaf, 0x23,
702 },
703 },
704 {
705 .in = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
706 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
707 .out = {
708 0x39, 0x28, 0xe1, 0x84, 0xfb, 0x86, 0x90, 0xf8,
709 0x40, 0xda, 0x39, 0x88, 0x12, 0x1d, 0x31, 0xbe,
710 0x65, 0xcb, 0x9d, 0x3e, 0xf8, 0x3e, 0xe6, 0x14,
711 0x6f, 0xea, 0xc8, 0x61, 0xe1, 0x9b, 0x56, 0x3a,
712 },
713 },
714 {
715 .in = "0123456701234567012345670123456701234567012345670123456701234567"
716 "0123456701234567012345670123456701234567012345670123456701234567"
717 "0123456701234567012345670123456701234567012345670123456701234567"
718 "0123456701234567012345670123456701234567012345670123456701234567"
719 "0123456701234567012345670123456701234567012345670123456701234567"
720 "0123456701234567012345670123456701234567012345670123456701234567"
721 "0123456701234567012345670123456701234567012345670123456701234567"
722 "0123456701234567012345670123456701234567012345670123456701234567"
723 "0123456701234567012345670123456701234567012345670123456701234567"
724 "0123456701234567012345670123456701234567012345670123456701234567",
725 .out = {
726 0xcf, 0x78, 0xe4, 0xba, 0x93, 0x5b, 0x4d, 0x9e,
727 0xb9, 0x10, 0x52, 0xae, 0xdd, 0xf8, 0xe2, 0xd6,
728 0x06, 0xc5, 0x90, 0xf7, 0x08, 0x57, 0x36, 0x93,
729 0xea, 0x94, 0xbe, 0x82, 0x6a, 0x66, 0x6e, 0xe4,
730 },
731 },
732};
733
734#define N_SHA512_256_TESTS (sizeof(sha512_256_tests) / sizeof(sha512_256_tests[0]))
735
736static void
737sha512_256_init(void *ctx)
738{
739 SHA512_256Init(ctx);
740}
741
742static void
743sha512_256_update(void *ctx, const uint8_t *data, size_t len)
744{
745 SHA512_256Update(ctx, data, len);
746}
747
748static void
749sha512_256_final(void *digest, void *ctx)
750{
751 SHA512_256Final(digest, ctx);
752}
753
754struct hash_ctx {
755 uint8_t *digest;
756 size_t digest_len;
757 void *ctx;
758 void (*init)(void *);
759 void (*update)(void *, const uint8_t *, size_t);
760 void (*final)(void *, void *);
761};
762
763static const struct hash_tests {
764 const char *name;
765 size_t num_tests;
766 const struct hash_test_case *tests;
767} hash_tests[] = {
768 [hash_md5] = {
769 .name = "RFC 1321 MD5",
770 .num_tests = N_MD5_TESTS,
771 .tests = md5_tests,
772 },
773 [hash_rmd160] = {
774 .name = "Bosselaers RMD160",
775 .num_tests = N_RMD160_TESTS,
776 .tests = rmd160_tests,
777 },
778 [hash_sha1] = {
779 .name = "RFC 3174 SHA1",
780 .num_tests = N_SHA1_TESTS,
781 .tests = sha1_tests,
782 },
783 [hash_sha224] = {
784 .name = "RFC 6234 SHA224",
785 .num_tests = N_SHA224_TESTS,
786 .tests = sha224_tests,
787 },
788 [hash_sha256] = {
789 .name = "RFC 6234 SHA256",
790 .num_tests = N_SHA256_TESTS,
791 .tests = sha256_tests,
792 },
793 [hash_sha384] = {
794 .name = "RFC 6234 SHA384",
795 .num_tests = N_SHA384_TESTS,
796 .tests = sha384_tests,
797 },
798 [hash_sha512] = {
799 .name = "RFC 6234 SHA512",
800 .num_tests = N_SHA512_TESTS,
801 .tests = sha512_tests,
802 },
803 [hash_sha512_256] = {
804 .name = "RFC 6234 SHA512_256 (generated)",
805 .num_tests = N_SHA512_256_TESTS,
806 .tests = sha512_256_tests,
807 },
808};
809
810static int
811hash_test_case(struct hash_ctx *ctx, const struct hash_test_case *tc,
812 const char *name, size_t testno)
813{
814 size_t in_len = tc->in != NULL ? strlen(tc->in) : 0;
815
816 ctx->init(ctx->ctx);
817 ctx->update(ctx->ctx, (const uint8_t *)tc->in, in_len);
818 ctx->final(ctx->digest, ctx->ctx);
819
820 if (memcmp(tc->out, ctx->digest, ctx->digest_len) != 0) {
821 fprintf(stderr, "FAIL: %s test %zu\n", name, testno);
822 return 1;
823 }
824
825 return 0;
826}
827
828static int
829hash_test(struct hash_ctx *ctx, const struct hash_tests *tests)
830{
831 size_t i;
832 int failed = 0;
833
834 for (i = 0; i < tests->num_tests; i++) {
835 const struct hash_test_case *tc = &tests->tests[i];
836
837 failed |= hash_test_case(ctx, tc, tests->name, i);
838 }
839
840 return failed;
841}
842
843int
844main(void)
845{
846 uint8_t md5_digest[MD5_DIGEST_LENGTH];
847 uint8_t rmd160_digest[RMD160_DIGEST_LENGTH];
848 uint8_t sha1_digest[SHA1_DIGEST_LENGTH];
849 uint8_t sha224_digest[SHA224_DIGEST_LENGTH];
850 uint8_t sha256_digest[SHA256_DIGEST_LENGTH];
851 uint8_t sha384_digest[SHA384_DIGEST_LENGTH];
852 uint8_t sha512_digest[SHA512_DIGEST_LENGTH];
853 uint8_t sha512_256_digest[SHA512_256_DIGEST_LENGTH];
854 MD5_CTX md5_ctx;
855 RMD160_CTX rmd160_ctx;
856 SHA1_CTX sha1_ctx;
857 SHA2_CTX sha224_ctx;
858 SHA2_CTX sha256_ctx;
859 SHA2_CTX sha384_ctx;
860 SHA2_CTX sha512_ctx;
861 SHA2_CTX sha512_256_ctx;
862 struct hash_ctx ctx[] = {
863 [hash_md5] = {
864 .digest = md5_digest,
865 .digest_len = sizeof(md5_digest),
866 .ctx = &md5_ctx,
867 .init = md5_init,
868 .update = md5_update,
869 .final = md5_final,
870 },
871 [hash_rmd160] = {
872 .digest = rmd160_digest,
873 .digest_len = sizeof(rmd160_digest),
874 .ctx = &rmd160_ctx,
875 .init = rmd160_init,
876 .update = rmd160_update,
877 .final = rmd160_final,
878 },
879 [hash_sha1] = {
880 .digest = sha1_digest,
881 .digest_len = sizeof(sha1_digest),
882 .ctx = &sha1_ctx,
883 .init = sha1_init,
884 .update = sha1_update,
885 .final = sha1_final,
886 },
887 [hash_sha224] = {
888 .digest = sha224_digest,
889 .digest_len = sizeof(sha224_digest),
890 .ctx = &sha224_ctx,
891 .init = sha224_init,
892 .update = sha224_update,
893 .final = sha224_final,
894 },
895 [hash_sha256] = {
896 .digest = sha256_digest,
897 .digest_len = sizeof(sha256_digest),
898 .ctx = &sha256_ctx,
899 .init = sha256_init,
900 .update = sha256_update,
901 .final = sha256_final,
902 },
903 [hash_sha384] = {
904 .digest = sha384_digest,
905 .digest_len = sizeof(sha384_digest),
906 .ctx = &sha384_ctx,
907 .init = sha384_init,
908 .update = sha384_update,
909 .final = sha384_final,
910 },
911 [hash_sha512] = {
912 .digest = sha512_digest,
913 .digest_len = sizeof(sha512_digest),
914 .ctx = &sha512_ctx,
915 .init = sha512_init,
916 .update = sha512_update,
917 .final = sha512_final,
918 },
919 [hash_sha512_256] = {
920 .digest = sha512_256_digest,
921 .digest_len = sizeof(sha512_256_digest),
922 .ctx = &sha512_256_ctx,
923 .init = sha512_256_init,
924 .update = sha512_256_update,
925 .final = sha512_256_final,
926 },
927 };
928 int i;
929 int failed = 0;
930
931 for (i = 0; i < NUM_HASHES; i++)
932 failed |= hash_test(&ctx[i], &hash_tests[i]);
933
934 return failed;
935}
diff --git a/src/regress/lib/libc/illumos/Makefile b/src/regress/lib/libc/illumos/Makefile
new file mode 100644
index 0000000000..cf2d22eb44
--- /dev/null
+++ b/src/regress/lib/libc/illumos/Makefile
@@ -0,0 +1,7 @@
1# $OpenBSD: Makefile,v 1.1.1.1 2025/08/02 06:16:34 tb Exp $
2
3SUBDIR += oclo
4
5install:
6
7.include <bsd.subdir.mk>
diff --git a/src/regress/lib/libc/illumos/Makefile.inc b/src/regress/lib/libc/illumos/Makefile.inc
new file mode 100644
index 0000000000..4296b6e690
--- /dev/null
+++ b/src/regress/lib/libc/illumos/Makefile.inc
@@ -0,0 +1,9 @@
1# $OpenBSD: Makefile.inc,v 1.1.1.1 2025/08/02 06:16:34 tb Exp $
2
3ILLUMOS_OS_TESTDIR = /usr/local/share/illumos-os-tests
4
5.if !exists(${ILLUMOS_OS_TESTDIR})
6regress:
7 @echo package illumos-os-tests is required for this regress
8 @echo SKIPPED
9.endif
diff --git a/src/regress/lib/libc/illumos/oclo/Makefile b/src/regress/lib/libc/illumos/oclo/Makefile
new file mode 100644
index 0000000000..c2c24202c3
--- /dev/null
+++ b/src/regress/lib/libc/illumos/oclo/Makefile
@@ -0,0 +1,16 @@
1# $OpenBSD: Makefile,v 1.1.1.1 2025/08/02 06:16:34 tb Exp $
2
3.if exists(/usr/local/share/illumos-os-tests)
4
5PROGS = oclo
6PROGS += oclo_errors
7PROGS += ocloexec_verify
8
9LDADD_ocloexec_verify = -lkvm
10
11WARNINGS = yes
12
13.PATH: /usr/local/share/illumos-os-tests/tests/oclo
14.endif
15
16.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/malloc/malloc_errs/malloc_errs.c b/src/regress/lib/libc/malloc/malloc_errs/malloc_errs.c
index 486c247f0d..57d799f49d 100644
--- a/src/regress/lib/libc/malloc/malloc_errs/malloc_errs.c
+++ b/src/regress/lib/libc/malloc/malloc_errs/malloc_errs.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: malloc_errs.c,v 1.5 2024/04/14 17:47:41 otto Exp $ */ 1/* $OpenBSD: malloc_errs.c,v 1.6 2025/05/24 06:40:29 otto Exp $ */
2/* 2/*
3 * Copyright (c) 2023 Otto Moerbeek <otto@drijf.net> 3 * Copyright (c) 2023 Otto Moerbeek <otto@drijf.net>
4 * 4 *
@@ -286,11 +286,10 @@ int main(int argc, char *argv[])
286 int i, status; 286 int i, status;
287 pid_t pid; 287 pid_t pid;
288 char num[10]; 288 char num[10];
289 char options[10]; 289 char options[40];
290 extern char* malloc_options; 290 char const *env[2];
291 291
292 if (argc == 3) { 292 if (argc == 2) {
293 malloc_options = argv[2];
294 /* prevent coredumps */ 293 /* prevent coredumps */
295 setrlimit(RLIMIT_CORE, &lim); 294 setrlimit(RLIMIT_CORE, &lim);
296 i = atoi(argv[1]); 295 i = atoi(argv[1]);
@@ -303,9 +302,11 @@ int main(int argc, char *argv[])
303 pid = fork(); 302 pid = fork();
304 switch (pid) { 303 switch (pid) {
305 case 0: 304 case 0:
306 snprintf(options, sizeof(options), "us%s", tests[i].flags); 305 snprintf(options, sizeof(options), "MALLOC_OPTIONS=us%s", tests[i].flags);
307 snprintf(num, sizeof(num), "%d", i); 306 snprintf(num, sizeof(num), "%d", i);
308 execl(argv[0], argv[0], num, options, NULL); 307 env[0] = options;
308 env[1] = NULL;
309 execle(argv[0], argv[0], num, NULL, env);
309 err(1, "exec"); 310 err(1, "exec");
310 break; 311 break;
311 case -1: 312 case -1:
diff --git a/src/regress/lib/libc/malloc/malloc_ulimit1/malloc_ulimit1.c b/src/regress/lib/libc/malloc/malloc_ulimit1/malloc_ulimit1.c
index 799d2b9117..7e53c32dbc 100644
--- a/src/regress/lib/libc/malloc/malloc_ulimit1/malloc_ulimit1.c
+++ b/src/regress/lib/libc/malloc/malloc_ulimit1/malloc_ulimit1.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: malloc_ulimit1.c,v 1.5 2019/06/12 11:31:36 bluhm Exp $ */ 1/* $OpenBSD: malloc_ulimit1.c,v 1.6 2025/05/24 06:47:27 otto Exp $ */
2 2
3/* Public Domain, 2006, Otto Moerbeek <otto@drijf.net> */ 3/* Public Domain, 2006, Otto Moerbeek <otto@drijf.net> */
4 4
@@ -23,7 +23,7 @@
23#define FACTOR 1024 23#define FACTOR 1024
24 24
25/* This test takes forever with junking turned on. */ 25/* This test takes forever with junking turned on. */
26char *malloc_options = "jj"; 26const char * const malloc_options = "jj";
27 27
28int 28int
29main() 29main()
diff --git a/src/regress/lib/libc/stdio/Makefile b/src/regress/lib/libc/stdio/Makefile
new file mode 100644
index 0000000000..f1e980f688
--- /dev/null
+++ b/src/regress/lib/libc/stdio/Makefile
@@ -0,0 +1,29 @@
1# $OpenBSD: Makefile,v 1.4 2025/06/03 14:35:27 yasuoka Exp $
2
3PROGS= test_fflush
4CLEANFILES= test_fflush.tmp
5
6PROGS+= test_ungetwc
7CLEANFILES+= test_ungetwc.tmp
8
9PROGS+= test___freading
10CLEANFILES+= test___freading.tmp
11
12PROGS+= test___fwriting
13CLEANFILES+= test___fwriting.tmp
14
15PROGS+= test___fpending
16CLEANFILES+= test___fpending.tmp
17
18PROGS+= test___freadahead
19CLEANFILES+= test___freadahead.tmp
20
21PROGS+= test___freadptr
22CLEANFILES+= test___freadptr.tmp
23
24PROGS+= test___fseterr
25CLEANFILES+= test___fseterr.tmp
26
27WARNINGS= yes
28
29.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/stdio/test___fpending.c b/src/regress/lib/libc/stdio/test___fpending.c
new file mode 100644
index 0000000000..96ace2e481
--- /dev/null
+++ b/src/regress/lib/libc/stdio/test___fpending.c
@@ -0,0 +1,58 @@
1/* $OpenBSD: test___fpending.c,v 1.1 2025/05/25 00:20:54 yasuoka Exp $ */
2
3/*
4 * Copyright (c) 2025 YASUOKA Masahiko <yasuoka@yasuoka.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <assert.h>
20#include <stdio.h>
21#include <stdio_ext.h>
22#include <stdlib.h>
23
24/* we use assert() */
25#undef NDEBUG
26
27#define TMPFILENAME "test___fpending.tmp"
28
29void test___fpending0(void);
30
31void
32test___fpending0(void)
33{
34 FILE *fp;
35 int r;
36 size_t s;
37
38 fp = fopen(TMPFILENAME, "w");
39 assert(fp != NULL);
40 r = fputs("Hello world", fp);
41 assert(r >= 0);
42 s = __fpending(fp);
43 assert(s > 0); /* assume buffered */
44 r = fflush(fp);
45 assert(r == 0);
46 s = __fpending(fp);
47 assert(s == 0); /* buffer must be 0 */
48 r = fclose(fp);
49 assert(r == 0);
50}
51
52int
53main(int argc, char *argv[])
54{
55 test___fpending0();
56
57 exit(0);
58}
diff --git a/src/regress/lib/libc/stdio/test___freadahead.c b/src/regress/lib/libc/stdio/test___freadahead.c
new file mode 100644
index 0000000000..66d5e3492a
--- /dev/null
+++ b/src/regress/lib/libc/stdio/test___freadahead.c
@@ -0,0 +1,71 @@
1/* $OpenBSD: test___freadahead.c,v 1.2 2025/06/03 14:35:27 yasuoka Exp $ */
2
3/*
4 * Copyright (c) 2025 YASUOKA Masahiko <yasuoka@yasuoka.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <assert.h>
20#include <errno.h>
21#include <stdio.h>
22#include <stdio_ext.h>
23#include <stdlib.h>
24
25/* we use assert() */
26#undef NDEBUG
27
28#define TMPFILENAME "test___freadahead.tmp"
29
30void test___freadahead0(void);
31
32void
33test___freadahead0(void)
34{
35 FILE *fp;
36 int r;
37 size_t s;
38
39 fp = fopen(TMPFILENAME, "w");
40 assert(fp != NULL);
41 r = fputs("Hello world", fp);
42 assert(r >= 0);
43 r = fclose(fp);
44
45 fp = fopen(TMPFILENAME, "r");
46 s = __freadahead(fp);
47 assert(s == 0);
48 assert(fgetc(fp) == 'H');
49 s = __freadahead(fp);
50 assert(s == 10);
51 r = fflush(fp);
52#if 0
53 /* fflush() to reading file is not supported (yet) */
54 assert(errno == EBADF);
55#else
56 assert(r == 0);
57 s = __freadahead(fp);
58 assert(s == 0);
59#endif
60
61 r = fclose(fp);
62 assert(r == 0);
63}
64
65int
66main(int argc, char *argv[])
67{
68 test___freadahead0();
69
70 exit(0);
71}
diff --git a/src/regress/lib/libc/stdio/test___freading.c b/src/regress/lib/libc/stdio/test___freading.c
new file mode 100644
index 0000000000..f74eb78d35
--- /dev/null
+++ b/src/regress/lib/libc/stdio/test___freading.c
@@ -0,0 +1,125 @@
1/* $OpenBSD: test___freading.c,v 1.2 2025/06/12 07:39:26 yasuoka Exp $ */
2
3/*
4 * Copyright (c) 2025 YASUOKA Masahiko <yasuoka@yasuoka.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <assert.h>
20#include <stdio.h>
21#include <stdio_ext.h>
22#include <stdlib.h>
23#include <string.h>
24#include <unistd.h>
25
26/* we use assert() */
27#undef NDEBUG
28
29#define TMPFILENAME "test___freading.tmp"
30
31void setup(void);
32
33void test___freading0(void);
34void test___freading1(void);
35void test___freading2(void);
36
37void
38setup(void)
39{
40 FILE *fp;
41
42 /* common setup */
43 unlink(TMPFILENAME);
44 fp = fopen(TMPFILENAME, "w+");
45 assert(fp != NULL);
46 fputs("Hello world\n", fp);
47 fclose(fp);
48}
49
50void
51test___freading0(void)
52{
53 FILE *fp;
54 int r;
55 char buf[80];
56
57 fp = popen("echo Hello world", "r");
58 assert(fp != NULL);
59 assert(__freading(fp) != 0);
60 assert(fgets(buf, sizeof(buf), fp) != NULL);
61 assert(strcmp(buf, "Hello world\n") == 0);
62 r = pclose(fp);
63 assert(r == 0);
64}
65
66void
67test___freading1(void)
68{
69 FILE *fp;
70 int r;
71
72 /* when the last operaiton is read, __freading() returns true */
73 fp = fopen(TMPFILENAME, "w+");
74 assert(fp != NULL);
75 assert(__freading(fp) == 0);
76 r = fputs("Hello world\n", fp);
77 assert(r >= 0);
78 assert(__freading(fp) == 0);
79 rewind(fp);
80 assert(fgetc(fp) == 'H');
81 assert(__freading(fp) != 0);
82 /* write */
83 fseek(fp, 0, SEEK_END);
84 r = fputs("\n", fp);
85 assert(__freading(fp) == 0);
86 /* ungetc */
87 rewind(fp);
88 assert(ungetc('X', fp) != 0);
89 assert(__freading(fp) != 0); /* reading */
90
91 r = fclose(fp);
92 assert(r == 0);
93}
94
95void
96test___freading2(void)
97{
98 int r;
99 FILE *fp;
100
101 /*
102 * until v1.10 of fpurge.c mistakenly enables the writing buffer
103 * without _SRD flag set.
104 */
105 fp = fopen(TMPFILENAME, "r+");
106 assert(fp != NULL);
107 assert(fgetc(fp) == 'H');
108 fpurge(fp);
109 fseek(fp, 0, SEEK_CUR);
110 assert(fputc('X', fp) == 'X');
111 assert(__freading(fp) == 0);
112
113 r = fclose(fp);
114 assert(r == 0);
115}
116
117int
118main(int argc, char *argv[])
119{
120 test___freading0();
121 test___freading1();
122 test___freading2();
123
124 exit(0);
125}
diff --git a/src/regress/lib/libc/stdio/test___freadptr.c b/src/regress/lib/libc/stdio/test___freadptr.c
new file mode 100644
index 0000000000..cce362f2ae
--- /dev/null
+++ b/src/regress/lib/libc/stdio/test___freadptr.c
@@ -0,0 +1,78 @@
1/* $OpenBSD: test___freadptr.c,v 1.1 2025/05/25 00:20:54 yasuoka Exp $ */
2
3/*
4 * Copyright (c) 2025 YASUOKA Masahiko <yasuoka@yasuoka.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20#include <assert.h>
21#include <stdio.h>
22#include <stdio_ext.h>
23#include <stdlib.h>
24#include <string.h>
25
26/* we use assert() */
27#undef NDEBUG
28
29#define TMPFILENAME "test___freadptr.tmp"
30
31void test___freadptr0(void);
32
33/* test __freadptr() and __freadptrinc() */
34void
35test___freadptr0(void)
36{
37 FILE *fp;
38 int r;
39 ssize_t s;
40 const char *p;
41
42 fp = fopen(TMPFILENAME, "w");
43 assert(fp != NULL);
44 r = fputs("Hello world", fp);
45 assert(r >= 0);
46 r = fclose(fp);
47
48 fp = fopen(TMPFILENAME, "r");
49 assert(fgetc(fp) == 'H');
50 p = __freadptr(fp, &s);
51 assert(p != NULL);
52 assert(s > 4); /* this test assume this (not by the spec) */
53 assert(*p == 'e');
54 assert(strncmp(p, "ello world", s) == 0);
55
56 __freadptrinc(fp, 4);
57 assert(fgetc(fp) == ' ');
58
59 ungetc('A', fp);
60 ungetc('A', fp);
61 ungetc('A', fp);
62 p = __freadptr(fp, &s);
63 assert(s > 0);
64 assert(*p == 'A');
65 /* ptr will contains only the pushback buffer */
66 assert(strncmp(p, "AAAworld", s) == 0);
67
68 r = fclose(fp);
69 assert(r == 0);
70}
71
72int
73main(int argc, char *argv[])
74{
75 test___freadptr0();
76
77 exit(0);
78}
diff --git a/src/regress/lib/libc/stdio/test___fseterr.c b/src/regress/lib/libc/stdio/test___fseterr.c
new file mode 100644
index 0000000000..70fb491c6c
--- /dev/null
+++ b/src/regress/lib/libc/stdio/test___fseterr.c
@@ -0,0 +1,60 @@
1/* $OpenBSD: test___fseterr.c,v 1.1 2025/05/25 00:20:54 yasuoka Exp $ */
2
3/*
4 * Copyright (c) 2025 YASUOKA Masahiko <yasuoka@yasuoka.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <assert.h>
20#include <stdio.h>
21#include <stdio_ext.h>
22#include <stdlib.h>
23
24/* we use assert() */
25#undef NDEBUG
26
27#define TMPFILENAME "test___fseterr.tmp"
28
29void test___fseterr0(void);
30
31void
32test___fseterr0(void)
33{
34 FILE *fp;
35 int r;
36
37 fp = fopen(TMPFILENAME, "w+");
38 assert(fp != NULL);
39
40 assert(!ferror(fp));
41
42 r = fprintf(fp, "hello world\n");
43 assert(r > 0);
44
45 __fseterr(fp);
46 assert(ferror(fp));
47
48 r = fprintf(fp, "hello world\n");
49 assert(r == -1);
50
51 fclose(fp);
52}
53
54int
55main(int argc, char *argv[])
56{
57 test___fseterr0();
58
59 exit(0);
60}
diff --git a/src/regress/lib/libc/stdio/test___fwriting.c b/src/regress/lib/libc/stdio/test___fwriting.c
new file mode 100644
index 0000000000..eb4671d3cf
--- /dev/null
+++ b/src/regress/lib/libc/stdio/test___fwriting.c
@@ -0,0 +1,83 @@
1/* $OpenBSD: test___fwriting.c,v 1.1 2025/05/25 00:20:54 yasuoka Exp $ */
2
3/*
4 * Copyright (c) 2025 YASUOKA Masahiko <yasuoka@yasuoka.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <assert.h>
20#include <stdio.h>
21#include <stdio_ext.h>
22#include <stdlib.h>
23
24/* we use assert() */
25#undef NDEBUG
26
27#define TMPFILENAME "test___fwriting.tmp"
28
29void test___fwriting0(void);
30void test___fwriting1(void);
31
32void
33test___fwriting0(void)
34{
35 FILE *fp;
36 int r;
37
38 fp = fopen(TMPFILENAME, "w"); /* write only */
39 assert(fp != NULL);
40 assert(__fwriting(fp) != 0); /* writing is true immediately */
41 r = fputs("Hello world\n", fp);
42 assert(r >= 0);
43 r = fclose(fp);
44 assert(r == 0);
45
46 fp = fopen(TMPFILENAME, "a"); /* append only */
47 assert(fp != NULL);
48 assert(__fwriting(fp) != 0); /* writing immediately */
49 r = fclose(fp);
50 assert(r == 0);
51}
52
53void
54test___fwriting1(void)
55{
56 FILE *fp;
57 int r;
58
59 fp = fopen(TMPFILENAME, "w+"); /* read / write */
60 assert(fp != NULL);
61 r = fputs("Hello world\n", fp);
62 assert(r >= 0);
63 assert(__fwriting(fp) != 0);
64 rewind(fp);
65 assert(fgetc(fp) == 'H'); /* read */
66 assert(__fwriting(fp) == 0); /* writing becomes false */
67 fputc('e', fp);
68 assert(__fwriting(fp) != 0); /* writing becomes true */
69 ungetc('e', fp);
70 assert(__fwriting(fp) == 0); /* ungetc -> writing becomes false */
71
72 r = fclose(fp);
73 assert(r == 0);
74}
75
76int
77main(int argc, char *argv[])
78{
79 test___fwriting0();
80 test___fwriting1();
81
82 exit(0);
83}
diff --git a/src/regress/lib/libc/stdio/test_fflush.c b/src/regress/lib/libc/stdio/test_fflush.c
new file mode 100644
index 0000000000..a0586b7d14
--- /dev/null
+++ b/src/regress/lib/libc/stdio/test_fflush.c
@@ -0,0 +1,345 @@
1/* $OpenBSD: test_fflush.c,v 1.3 2025/06/08 08:53:53 yasuoka Exp $ */
2
3/*
4 * Copyright (c) 2025 YASUOKA Masahiko <yasuoka@yasuoka.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <assert.h>
20#include <locale.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <unistd.h>
25#include <wchar.h>
26
27/* we use assert() */
28#undef NDEBUG
29
30#define TMPFILENAME "test_fflush.tmp"
31
32void setup(void);
33
34void test_fflush_read0(void);
35void test_fflush_read1(void);
36void test_fflush_read2(void);
37void test_fflush_read3(void);
38void test_fflush_read4(void);
39void setupw(void);
40void test_fflush_read5(void);
41void test_fflush_read6(void);
42
43void
44setup(void)
45{
46 FILE *fp;
47
48 /* common setup */
49 unlink(TMPFILENAME);
50 fp = fopen(TMPFILENAME, "w+");
51 assert(fp != NULL);
52 fputs("Hello world\n", fp);
53 fclose(fp);
54}
55
56/* fflush work with reading file and seekable */
57void
58test_fflush_read0(void)
59{
60 int r;
61 char buf[80];
62 FILE *fp;
63
64 setup();
65
66 /* In POSIX 2008, fflush() must work with the file object for reading */
67 fp = fopen(TMPFILENAME, "r");
68 assert(fp != NULL);
69 assert(fgetc(fp) == 'H');
70 r = fflush(fp);
71 assert(r == 0);
72
73 /* the position is moved to 1 */
74 assert(ftell(fp) == 1);
75
76 /* can read rest of that */
77 fgets(buf, sizeof(buf), fp);
78 assert(strcmp(buf, "ello world\n") == 0);
79 r = fclose(fp);
80 assert(r == 0);
81}
82
83/* fflush work with reading file and seekable + unget */
84void
85test_fflush_read1(void)
86{
87 int r;
88 char buf[80];
89 FILE *fp;
90
91 setup();
92
93 fp = fopen(TMPFILENAME, "r");
94 assert(fp != NULL);
95 assert(fgetc(fp) == 'H');
96 assert(fgetc(fp) == 'e');
97 assert(fgetc(fp) == 'l');
98 assert(fgetc(fp) == 'l');
99 assert(fgetc(fp) == 'o');
100
101 /* push the 'AAAA' back */
102 ungetc('A', fp);
103 ungetc('A', fp);
104 ungetc('A', fp);
105 ungetc('A', fp);
106
107 /* can read rest of that */
108 fgets(buf, sizeof(buf), fp);
109 assert(strcmp(buf, "AAAA world\n") == 0);
110 r = fclose(fp);
111 assert(r == 0);
112
113 /* do the same thing + fflush */
114
115 fp = fopen(TMPFILENAME, "r");
116 assert(fp != NULL);
117 assert(fgetc(fp) == 'H');
118 assert(fgetc(fp) == 'e');
119 assert(fgetc(fp) == 'l');
120 assert(fgetc(fp) == 'l');
121 assert(fgetc(fp) == 'o');
122
123 /* push 'AAAA' back */
124 ungetc('A', fp);
125 ungetc('A', fp);
126 ungetc('A', fp);
127 ungetc('A', fp);
128
129 /* then fflush */
130 r = fflush(fp);
131 assert(r == 0);
132
133 /* fllush() clears the all pushed back chars */
134
135 /* can read rest of that */
136 fgets(buf, sizeof(buf), fp);
137 assert(strcmp(buf, " world\n") == 0);
138 r = fclose(fp);
139 assert(r == 0);
140}
141
142/* fflush() to reading and non-seekable stream */
143void
144test_fflush_read2(void)
145{
146 int r;
147 FILE *fp;
148 char buf[80];
149
150 /* In POSIX-2008, fflush() must work with the file object for reading */
151 fp = popen("echo Hello world", "r");
152 assert(fp != NULL);
153 assert(fgetc(fp) == 'H');
154 r = fflush(fp);
155 assert(r == 0);
156
157 /*
158 * FILE object for read and NOT seekable. In that case, fflush does
159 * nothing, but must keep the buffer.
160 */
161
162 /* can read rest of that */
163 fgets(buf, sizeof(buf), fp);
164 assert(strcmp(buf, "ello world\n") == 0);
165 r = pclose(fp);
166 assert(r == 0);
167}
168
169/* fflush() to the file which doesn't have any buffer */
170void
171test_fflush_read3(void)
172{
173 int r;
174 FILE *fp;
175
176 setup();
177
178 /* In POSIX-2008, fflush() must work with the file object for reading */
179 fp = fopen(TMPFILENAME, "r");
180 assert(fp != NULL);
181 r = fflush(fp);
182 assert(r == 0);
183 r = fclose(fp);
184 assert(r == 0);
185}
186
187/* freopen() should call fflush() internal */
188void
189test_fflush_read4(void)
190{
191 int r;
192 FILE *fp;
193 off_t pos;
194 char buf[80];
195
196 setup();
197
198 /* In POSIX-2008, fflush() must work with the file object for reading */
199 fp = fopen(TMPFILENAME, "r");
200 assert(fp != NULL);
201
202 assert(fgetc(fp) == 'H'); /* read 1 */
203
204 pos = lseek(fileno(fp), 0, SEEK_CUR);
205 assert(pos >= 1);
206 assert(pos > 1); /* this test assume the buffer is used */
207
208 /* freopen() should call fflush() internal */
209 fp = freopen(TMPFILENAME, "r", fp);
210 assert(fp != NULL);
211
212 /* can read rest of that on fp */
213 fgets(buf, sizeof(buf), fp);
214 assert(strcmp(buf, "Hello world\n") == 0);
215
216 r = fclose(fp);
217 assert(r == 0);
218}
219
220void
221setupw(void)
222{
223 FILE *fp;
224
225 /* common setup */
226 unlink(TMPFILENAME);
227 fp = fopen(TMPFILENAME, "w+");
228 assert(fp != NULL);
229 /* Konnitiwa Sekai(in Kanji) */
230 fputws(L"\u3053\u3093\u306b\u3061\u308f \u4e16\u754c\n", fp);
231 fclose(fp);
232}
233
234/* fflush work with reading file and seekable + ungetwc */
235void
236test_fflush_read5(void)
237{
238 int r;
239 wchar_t buf[80];
240 FILE *fp;
241
242 setupw();
243
244 fp = fopen(TMPFILENAME, "r");
245
246 assert(fp != NULL);
247 assert(fgetwc(fp) == L'\u3053'); /* Ko */
248 assert(fgetwc(fp) == L'\u3093'); /* N */
249 assert(fgetwc(fp) == L'\u306b'); /* Ni */
250 assert(fgetwc(fp) == L'\u3061'); /* Ti */
251 assert(fgetwc(fp) == L'\u308f'); /* Wa */
252
253 /* push 263A(smile) back */
254 assert(ungetwc(L'\u263a', fp));
255
256 /* we support 1 push back wchar_t */
257 assert(fgetwc(fp) == L'\u263a');
258
259 /* can read reset of that */
260 fgetws(buf, sizeof(buf), fp);
261 assert(wcscmp(buf, L" \u4e16\u754c\n") == 0);
262
263 r = fclose(fp);
264 assert(r == 0);
265
266 /* do the same thing + fflush */
267 fp = fopen(TMPFILENAME, "r");
268
269 assert(fp != NULL);
270 assert(fgetwc(fp) == L'\u3053'); /* Ko */
271 assert(fgetwc(fp) == L'\u3093'); /* N */
272 assert(fgetwc(fp) == L'\u306b'); /* Ni */
273 assert(fgetwc(fp) == L'\u3061'); /* Ti */
274 assert(fgetwc(fp) == L'\u308f'); /* Wa */
275
276 /* push 263A(smile) back */
277 assert(ungetwc(L'\u263a', fp));
278
279 /* we support 1 push back wchar_t */
280 assert(fgetwc(fp) == L'\u263a');
281
282 /* then fflush */
283 r = fflush(fp);
284 assert(r == 0);
285
286 /* fllush() clears the all pushed back chars */
287
288 /* can read rest of that */
289 fgetws(buf, sizeof(buf), fp);
290 assert(wcscmp(buf, L" \u4e16\u754c\n") == 0);
291 r = fclose(fp);
292 assert(r == 0);
293}
294
295void
296test_fflush_read6(void)
297{
298 int r, c;
299 FILE *fp;
300
301 setup();
302 fp = fopen(TMPFILENAME, "r");
303 assert(fp != NULL);
304
305 /*
306 * https://pubs.opengroup.org/onlinepubs/9699919799/functions/fflush.html
307 * .. any characters pushed back onto the stream by ungetc() or ungetwc()
308 * that have not subsequently been read from the stream shall be discarded
309 * (without further changing the file offset).
310 */
311
312 assert(fgetc(fp) == 'H');
313 c = getc(fp);
314 ungetc(c, fp); /* push back the character has been read */
315 r = fflush(fp);
316 assert(r == 0);
317 assert(getc(fp) == c);
318
319 fseek(fp, 0, SEEK_SET);
320 assert(fgetc(fp) == 'H');
321 c = getc(fp);
322 ungetc('X', fp); /* push back the character has not been read */
323 r = fflush(fp);
324 assert(r == 0);
325 assert(getc(fp) == 'l');
326
327 r = fclose(fp);
328 assert(r == 0);
329}
330
331int
332main(int argc, char *argv[])
333{
334 setlocale(LC_ALL, "C.UTF-8");
335
336 test_fflush_read0();
337 test_fflush_read1();
338 test_fflush_read2();
339 test_fflush_read3();
340 test_fflush_read4();
341 test_fflush_read5();
342 test_fflush_read6();
343
344 exit(0);
345}
diff --git a/src/regress/lib/libc/stdio/test_ungetwc.c b/src/regress/lib/libc/stdio/test_ungetwc.c
new file mode 100644
index 0000000000..bb4e853020
--- /dev/null
+++ b/src/regress/lib/libc/stdio/test_ungetwc.c
@@ -0,0 +1,90 @@
1/* $OpenBSD: test_ungetwc.c,v 1.1 2025/05/25 05:32:45 yasuoka Exp $ */
2
3/*
4 * Copyright (c) 2025 YASUOKA Masahiko <yasuoka@yasuoka.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <assert.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <unistd.h>
24#include <locale.h>
25#include <wchar.h>
26
27/* we use assert() */
28#undef NDEBUG
29
30#define TMPFILENAME "test_ungetwc.tmp"
31
32void setupw(void);
33void test_fflush_ungetwc0(void);
34
35void
36setupw(void)
37{
38 FILE *fp;
39
40 /* common setup */
41 unlink(TMPFILENAME);
42 fp = fopen(TMPFILENAME, "w+");
43 assert(fp != NULL);
44 /* Konnitiwa Sekai(in Kanji) */
45 fputws(L"\u3053\u3093\u306b\u3061\u308f \u4e16\u754c\n", fp);
46 fclose(fp);
47}
48
49/* fflush work with reading file and seekable + ungetwc */
50void
51test_fflush_ungetwc0(void)
52{
53 int r;
54 wchar_t buf[80];
55 FILE *fp;
56
57 setupw();
58
59 fp = fopen(TMPFILENAME, "r");
60
61 assert(fp != NULL);
62 assert(fgetwc(fp) == L'\u3053'); /* Ko */
63 assert(fgetwc(fp) == L'\u3093'); /* N */
64 assert(fgetwc(fp) == L'\u306b'); /* Ni */
65 assert(fgetwc(fp) == L'\u3061'); /* Ti */
66 assert(fgetwc(fp) == L'\u308f'); /* Wa */
67
68 /* push 263A(smile) back */
69 assert(ungetwc(L'\u263a', fp));
70
71 /* we support 1 push back wchar_t */
72 assert(fgetwc(fp) == L'\u263a');
73
74 /* can read reset of that */
75 fgetws(buf, sizeof(buf), fp);
76 assert(wcscmp(buf, L" \u4e16\u754c\n") == 0);
77
78 r = fclose(fp);
79 assert(r == 0);
80}
81
82int
83main(int argc, char *argv[])
84{
85 setlocale(LC_ALL, "C.UTF-8");
86
87 test_fflush_ungetwc0();
88
89 exit(0);
90}