xref: /netbsd-src/tests/lib/libc/string/t_memset.c (revision b7152c324c52acdae196766ae19dab96f1d64ea1)
1*b7152c32Sriastradh /* $NetBSD: t_memset.c,v 1.5 2024/11/02 02:43:48 riastradh Exp $ */
20df0be27Sjruoho 
30df0be27Sjruoho /*-
40df0be27Sjruoho  * Copyright (c) 2011 The NetBSD Foundation, Inc.
50df0be27Sjruoho  * All rights reserved.
60df0be27Sjruoho  *
70df0be27Sjruoho  * This code is derived from software contributed to The NetBSD Foundation
80df0be27Sjruoho  * by Jukka Ruohonen.
90df0be27Sjruoho  *
100df0be27Sjruoho  * Redistribution and use in source and binary forms, with or without
110df0be27Sjruoho  * modification, are permitted provided that the following conditions
120df0be27Sjruoho  * are met:
130df0be27Sjruoho  * 1. Redistributions of source code must retain the above copyright
140df0be27Sjruoho  *    notice, this list of conditions and the following disclaimer.
150df0be27Sjruoho  * 2. Redistributions in binary form must reproduce the above copyright
160df0be27Sjruoho  *    notice, this list of conditions and the following disclaimer in the
170df0be27Sjruoho  *    documentation and/or other materials provided with the distribution.
180df0be27Sjruoho  *
190df0be27Sjruoho  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
200df0be27Sjruoho  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
210df0be27Sjruoho  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
220df0be27Sjruoho  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
230df0be27Sjruoho  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
240df0be27Sjruoho  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
250df0be27Sjruoho  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
260df0be27Sjruoho  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
270df0be27Sjruoho  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
280df0be27Sjruoho  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
290df0be27Sjruoho  * POSSIBILITY OF SUCH DAMAGE.
300df0be27Sjruoho  */
310df0be27Sjruoho #include <sys/cdefs.h>
32*b7152c32Sriastradh __RCSID("$NetBSD: t_memset.c,v 1.5 2024/11/02 02:43:48 riastradh Exp $");
330df0be27Sjruoho 
340df0be27Sjruoho #include <sys/stat.h>
350df0be27Sjruoho 
360df0be27Sjruoho #include <atf-c.h>
370df0be27Sjruoho #include <stdlib.h>
380df0be27Sjruoho #include <string.h>
390df0be27Sjruoho #include <unistd.h>
400df0be27Sjruoho 
410df0be27Sjruoho static long	page = 0;
420df0be27Sjruoho static void	fill(char *, size_t, char);
430df0be27Sjruoho static bool	check(char *, size_t, char);
440df0be27Sjruoho 
454c5334afSmartin int zero;	/* always zero, but the compiler does not know */
464c5334afSmartin 
47*b7152c32Sriastradh static const struct {
48*b7152c32Sriastradh 	const char	*name;
49*b7152c32Sriastradh 	void		*(*fn)(void *, int, size_t);
50*b7152c32Sriastradh } memsetfn[] = {
51*b7152c32Sriastradh 	{ "memset", &memset },
52*b7152c32Sriastradh 	{ "explicit_memset", &explicit_memset }, /* NetBSD extension */
53*b7152c32Sriastradh 	{ "memset_explicit", &memset_explicit }, /* C23 adopted name */
54*b7152c32Sriastradh };
55*b7152c32Sriastradh 
560df0be27Sjruoho ATF_TC(memset_array);
570df0be27Sjruoho ATF_TC_HEAD(memset_array, tc)
580df0be27Sjruoho {
590df0be27Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test memset(3) with arrays");
600df0be27Sjruoho }
610df0be27Sjruoho 
620df0be27Sjruoho ATF_TC_BODY(memset_array, tc)
630df0be27Sjruoho {
640df0be27Sjruoho 	char buf[1024];
65*b7152c32Sriastradh 	unsigned i;
660df0be27Sjruoho 
67*b7152c32Sriastradh 	for (i = 0; i < __arraycount(memsetfn); i++) {
68*b7152c32Sriastradh 		(void)(*memsetfn[i].fn)(buf, 0, sizeof(buf));
69*b7152c32Sriastradh 		ATF_CHECK_MSG(check(buf, sizeof(buf), 0),
70*b7152c32Sriastradh 		    "%s did not fill a static buffer",
71*b7152c32Sriastradh 		    memsetfn[i].name);
720df0be27Sjruoho 
73*b7152c32Sriastradh 		(void)(*memsetfn[i].fn)(buf, 'x', sizeof(buf));
74*b7152c32Sriastradh 		ATF_CHECK_MSG(check(buf, sizeof(buf), 'x'),
75*b7152c32Sriastradh 		    "%s did not fill a static buffer",
76*b7152c32Sriastradh 		    memsetfn[i].name);
77*b7152c32Sriastradh 	}
780df0be27Sjruoho }
790df0be27Sjruoho 
80d3d55324Schristos ATF_TC(memset_return);
81d3d55324Schristos ATF_TC_HEAD(memset_return, tc)
82d3d55324Schristos {
83d3d55324Schristos 	atf_tc_set_md_var(tc, "descr", "Test memset(3) return value");
84d3d55324Schristos }
85d3d55324Schristos 
86d3d55324Schristos ATF_TC_BODY(memset_return, tc)
87d3d55324Schristos {
88d3d55324Schristos 	char *b = (char *)0x1;
89d3d55324Schristos 	char c[2];
90*b7152c32Sriastradh 	char *p;
91*b7152c32Sriastradh 	unsigned i;
92*b7152c32Sriastradh 
93*b7152c32Sriastradh 	for (i = 0; i < __arraycount(memsetfn); i++) {
94*b7152c32Sriastradh 		ATF_CHECK_EQ_MSG((p = (*memsetfn[i].fn)(b, 0, 0)), b,
95*b7152c32Sriastradh 		    "%s: returned %p, expected %p", memsetfn[i].name, p, b);
96*b7152c32Sriastradh 		ATF_CHECK_EQ_MSG((p = (*memsetfn[i].fn)(c, 2, sizeof(c))), c,
97*b7152c32Sriastradh 		    "%s: returned %p, expected %p", memsetfn[i].name, p, c);
98*b7152c32Sriastradh 	}
99d3d55324Schristos }
100d3d55324Schristos 
1010df0be27Sjruoho ATF_TC(memset_basic);
1020df0be27Sjruoho ATF_TC_HEAD(memset_basic, tc)
1030df0be27Sjruoho {
1040df0be27Sjruoho 	atf_tc_set_md_var(tc, "descr", "A basic test of memset(3)");
1050df0be27Sjruoho }
1060df0be27Sjruoho 
1070df0be27Sjruoho ATF_TC_BODY(memset_basic, tc)
1080df0be27Sjruoho {
1090df0be27Sjruoho 	char *buf, *ret;
110*b7152c32Sriastradh 	unsigned i;
1110df0be27Sjruoho 
1120df0be27Sjruoho 	buf = malloc(page);
1130df0be27Sjruoho 	ret = malloc(page);
1140df0be27Sjruoho 
1150df0be27Sjruoho 	ATF_REQUIRE(buf != NULL);
1160df0be27Sjruoho 	ATF_REQUIRE(ret != NULL);
1170df0be27Sjruoho 
118*b7152c32Sriastradh 	for (i = 0; i < __arraycount(memsetfn); i++) {
1190df0be27Sjruoho 		fill(ret, page, 0);
120*b7152c32Sriastradh 		(*memsetfn[i].fn)(buf, 0, page);
1210df0be27Sjruoho 
122*b7152c32Sriastradh 		ATF_CHECK_EQ_MSG(memcmp(ret, buf, page), 0, "%s",
123*b7152c32Sriastradh 		    memsetfn[i].name);
1240df0be27Sjruoho 
1250df0be27Sjruoho 		fill(ret, page, 'x');
126*b7152c32Sriastradh 		(*memsetfn[i].fn)(buf, 'x', page);
1270df0be27Sjruoho 
128*b7152c32Sriastradh 		ATF_CHECK_EQ_MSG(memcmp(ret, buf, page), 0, "%s",
129*b7152c32Sriastradh 		    memsetfn[i].name);
130*b7152c32Sriastradh 	}
1310df0be27Sjruoho 
1320df0be27Sjruoho 	free(buf);
1330df0be27Sjruoho 	free(ret);
1340df0be27Sjruoho }
1350df0be27Sjruoho 
1360df0be27Sjruoho ATF_TC(memset_nonzero);
1370df0be27Sjruoho ATF_TC_HEAD(memset_nonzero, tc)
1380df0be27Sjruoho {
1390df0be27Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test memset(3) with non-zero params");
1400df0be27Sjruoho }
1410df0be27Sjruoho 
1420df0be27Sjruoho ATF_TC_BODY(memset_nonzero, tc)
1430df0be27Sjruoho {
1440df0be27Sjruoho 	const size_t n = 0x7f;
1450df0be27Sjruoho 	char *buf;
146*b7152c32Sriastradh 	size_t i, j;
1470df0be27Sjruoho 
1480df0be27Sjruoho 	buf = malloc(page);
1490df0be27Sjruoho 	ATF_REQUIRE(buf != NULL);
1500df0be27Sjruoho 
1510df0be27Sjruoho 	for (i = 0x21; i < n; i++) {
152*b7152c32Sriastradh 		for (j = 0; j < __arraycount(memsetfn); j++) {
153*b7152c32Sriastradh 			(void)(*memsetfn[j].fn)(buf, i, page);
154*b7152c32Sriastradh 			ATF_CHECK_MSG(check(buf, page, i),
155*b7152c32Sriastradh 			    "%s did not fill properly with %zu",
156*b7152c32Sriastradh 			    memsetfn[j].name, i);
157*b7152c32Sriastradh 		}
1580df0be27Sjruoho 	}
1590df0be27Sjruoho 
1600df0be27Sjruoho 	free(buf);
1610df0be27Sjruoho }
1620df0be27Sjruoho 
1634c5334afSmartin ATF_TC(memset_zero_size);
1644c5334afSmartin 
1654c5334afSmartin ATF_TC_HEAD(memset_zero_size, tc)
1664c5334afSmartin {
1674c5334afSmartin 	atf_tc_set_md_var(tc, "descr", "Test memset(3) with zero size");
1684c5334afSmartin }
1694c5334afSmartin 
1704c5334afSmartin ATF_TC_BODY(memset_zero_size, tc)
1714c5334afSmartin {
1724c5334afSmartin 	char buf[1024];
173*b7152c32Sriastradh 	unsigned i;
1744c5334afSmartin 
175*b7152c32Sriastradh 	for (i = 0; i < __arraycount(memsetfn); i++) {
176*b7152c32Sriastradh 		(void)(*memsetfn[i].fn)(buf, 'x', sizeof(buf));
177*b7152c32Sriastradh 		ATF_CHECK_MSG(check(buf, sizeof(buf), 'x'),
178*b7152c32Sriastradh 		    "%s did not fill a static buffer",
179*b7152c32Sriastradh 		    memsetfn[i].name);
1804c5334afSmartin 
1814c5334afSmartin 		(void)memset(buf+sizeof(buf)/2, 0, zero);
182*b7152c32Sriastradh 		ATF_CHECK_MSG(check(buf, sizeof(buf), 'x'),
183*b7152c32Sriastradh 		    "%s with 0 size did change the buffer",
184*b7152c32Sriastradh 		    memsetfn[i].name);
185*b7152c32Sriastradh 	}
1864c5334afSmartin }
1874c5334afSmartin 
1884c5334afSmartin ATF_TC(bzero_zero_size);
1894c5334afSmartin 
1904c5334afSmartin ATF_TC_HEAD(bzero_zero_size, tc)
1914c5334afSmartin {
1924c5334afSmartin 	atf_tc_set_md_var(tc, "descr", "Test bzero(3) with zero size");
1934c5334afSmartin }
1944c5334afSmartin 
1954c5334afSmartin ATF_TC_BODY(bzero_zero_size, tc)
1964c5334afSmartin {
1974c5334afSmartin 	char buf[1024];
1984c5334afSmartin 
1994c5334afSmartin 	(void)memset(buf, 'x', sizeof(buf));
2004c5334afSmartin 
2014c5334afSmartin 	if (check(buf, sizeof(buf), 'x') != true)
2024c5334afSmartin 		atf_tc_fail("memset(3) did not fill a static buffer");
2034c5334afSmartin 
2044c5334afSmartin 	(void)bzero(buf+sizeof(buf)/2, zero);
2054c5334afSmartin 
2064c5334afSmartin 	if (check(buf, sizeof(buf), 'x') != true)
2074c5334afSmartin 		atf_tc_fail("bzero(3) with 0 size did change the buffer");
2084c5334afSmartin }
2094c5334afSmartin 
2100df0be27Sjruoho ATF_TC(memset_struct);
2110df0be27Sjruoho ATF_TC_HEAD(memset_struct, tc)
2120df0be27Sjruoho {
2130df0be27Sjruoho 	atf_tc_set_md_var(tc, "descr", "Test memset(3) with a structure");
2140df0be27Sjruoho }
2150df0be27Sjruoho 
2160df0be27Sjruoho ATF_TC_BODY(memset_struct, tc)
2170df0be27Sjruoho {
2180df0be27Sjruoho 	struct stat st;
219*b7152c32Sriastradh 	unsigned i;
2200df0be27Sjruoho 
221*b7152c32Sriastradh 	for (i = 0; i < __arraycount(memsetfn); i++) {
2220df0be27Sjruoho 		st.st_dev = 0;
2230df0be27Sjruoho 		st.st_ino = 1;
2240df0be27Sjruoho 		st.st_mode = 2;
2250df0be27Sjruoho 		st.st_nlink = 3;
2260df0be27Sjruoho 		st.st_uid = 4;
2270df0be27Sjruoho 		st.st_gid = 5;
2280df0be27Sjruoho 		st.st_rdev = 6;
2290df0be27Sjruoho 		st.st_size = 7;
2300df0be27Sjruoho 		st.st_atime = 8;
2310df0be27Sjruoho 		st.st_mtime = 9;
2320df0be27Sjruoho 
233*b7152c32Sriastradh 		(void)(*memsetfn[i].fn)(&st, 0, sizeof(struct stat));
2340df0be27Sjruoho 
235*b7152c32Sriastradh 		ATF_CHECK_MSG(st.st_dev == 0, "%s", memsetfn[i].name);
236*b7152c32Sriastradh 		ATF_CHECK_MSG(st.st_ino == 0, "%s", memsetfn[i].name);
237*b7152c32Sriastradh 		ATF_CHECK_MSG(st.st_mode == 0, "%s", memsetfn[i].name);
238*b7152c32Sriastradh 		ATF_CHECK_MSG(st.st_nlink == 0, "%s", memsetfn[i].name);
239*b7152c32Sriastradh 		ATF_CHECK_MSG(st.st_uid == 0, "%s", memsetfn[i].name);
240*b7152c32Sriastradh 		ATF_CHECK_MSG(st.st_gid == 0, "%s", memsetfn[i].name);
241*b7152c32Sriastradh 		ATF_CHECK_MSG(st.st_rdev == 0, "%s", memsetfn[i].name);
242*b7152c32Sriastradh 		ATF_CHECK_MSG(st.st_size == 0, "%s", memsetfn[i].name);
243*b7152c32Sriastradh 		ATF_CHECK_MSG(st.st_atime == 0, "%s", memsetfn[i].name);
244*b7152c32Sriastradh 		ATF_CHECK_MSG(st.st_mtime == 0, "%s", memsetfn[i].name);
245*b7152c32Sriastradh 	}
2460df0be27Sjruoho }
2470df0be27Sjruoho 
2480df0be27Sjruoho static void
2490df0be27Sjruoho fill(char *buf, size_t len, char x)
2500df0be27Sjruoho {
2510df0be27Sjruoho 	size_t i;
2520df0be27Sjruoho 
2530df0be27Sjruoho 	for (i = 0; i < len; i++)
2540df0be27Sjruoho 		buf[i] = x;
2550df0be27Sjruoho }
2560df0be27Sjruoho 
2570df0be27Sjruoho static bool
2580df0be27Sjruoho check(char *buf, size_t len, char x)
2590df0be27Sjruoho {
2600df0be27Sjruoho 	size_t i;
2610df0be27Sjruoho 
2620df0be27Sjruoho 	for (i = 0; i < len; i++) {
2630df0be27Sjruoho 
2640df0be27Sjruoho 		if (buf[i] != x)
2650df0be27Sjruoho 			return false;
2660df0be27Sjruoho 	}
2670df0be27Sjruoho 
2680df0be27Sjruoho 	return true;
2690df0be27Sjruoho }
2700df0be27Sjruoho 
2710df0be27Sjruoho ATF_TP_ADD_TCS(tp)
2720df0be27Sjruoho {
2730df0be27Sjruoho 
2740df0be27Sjruoho 	page = sysconf(_SC_PAGESIZE);
2750df0be27Sjruoho 	ATF_REQUIRE(page >= 0);
2760df0be27Sjruoho 
2770df0be27Sjruoho 	ATF_TP_ADD_TC(tp, memset_array);
2780df0be27Sjruoho 	ATF_TP_ADD_TC(tp, memset_basic);
2790df0be27Sjruoho 	ATF_TP_ADD_TC(tp, memset_nonzero);
2800df0be27Sjruoho 	ATF_TP_ADD_TC(tp, memset_struct);
281d3d55324Schristos 	ATF_TP_ADD_TC(tp, memset_return);
2824c5334afSmartin 	ATF_TP_ADD_TC(tp, memset_zero_size);
2834c5334afSmartin 	ATF_TP_ADD_TC(tp, bzero_zero_size);
2840df0be27Sjruoho 
2850df0be27Sjruoho 	return atf_no_error();
2860df0be27Sjruoho }
287