1 1.5 riastrad /* $NetBSD: t_memset.c,v 1.5 2024/11/02 02:43:48 riastradh Exp $ */ 2 1.1 jruoho 3 1.1 jruoho /*- 4 1.1 jruoho * Copyright (c) 2011 The NetBSD Foundation, Inc. 5 1.1 jruoho * All rights reserved. 6 1.1 jruoho * 7 1.1 jruoho * This code is derived from software contributed to The NetBSD Foundation 8 1.1 jruoho * by Jukka Ruohonen. 9 1.1 jruoho * 10 1.1 jruoho * Redistribution and use in source and binary forms, with or without 11 1.1 jruoho * modification, are permitted provided that the following conditions 12 1.1 jruoho * are met: 13 1.1 jruoho * 1. Redistributions of source code must retain the above copyright 14 1.1 jruoho * notice, this list of conditions and the following disclaimer. 15 1.1 jruoho * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 jruoho * notice, this list of conditions and the following disclaimer in the 17 1.1 jruoho * documentation and/or other materials provided with the distribution. 18 1.1 jruoho * 19 1.1 jruoho * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 jruoho * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 jruoho * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 jruoho * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 jruoho * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 jruoho * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 jruoho * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 jruoho * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 jruoho * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 jruoho * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 jruoho * POSSIBILITY OF SUCH DAMAGE. 30 1.1 jruoho */ 31 1.1 jruoho #include <sys/cdefs.h> 32 1.5 riastrad __RCSID("$NetBSD: t_memset.c,v 1.5 2024/11/02 02:43:48 riastradh Exp $"); 33 1.1 jruoho 34 1.1 jruoho #include <sys/stat.h> 35 1.1 jruoho 36 1.1 jruoho #include <atf-c.h> 37 1.1 jruoho #include <stdlib.h> 38 1.1 jruoho #include <string.h> 39 1.1 jruoho #include <unistd.h> 40 1.1 jruoho 41 1.1 jruoho static long page = 0; 42 1.1 jruoho static void fill(char *, size_t, char); 43 1.1 jruoho static bool check(char *, size_t, char); 44 1.1 jruoho 45 1.4 martin int zero; /* always zero, but the compiler does not know */ 46 1.4 martin 47 1.5 riastrad static const struct { 48 1.5 riastrad const char *name; 49 1.5 riastrad void *(*fn)(void *, int, size_t); 50 1.5 riastrad } memsetfn[] = { 51 1.5 riastrad { "memset", &memset }, 52 1.5 riastrad { "explicit_memset", &explicit_memset }, /* NetBSD extension */ 53 1.5 riastrad { "memset_explicit", &memset_explicit }, /* C23 adopted name */ 54 1.5 riastrad }; 55 1.5 riastrad 56 1.1 jruoho ATF_TC(memset_array); 57 1.1 jruoho ATF_TC_HEAD(memset_array, tc) 58 1.1 jruoho { 59 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test memset(3) with arrays"); 60 1.1 jruoho } 61 1.1 jruoho 62 1.1 jruoho ATF_TC_BODY(memset_array, tc) 63 1.1 jruoho { 64 1.1 jruoho char buf[1024]; 65 1.5 riastrad unsigned i; 66 1.1 jruoho 67 1.5 riastrad for (i = 0; i < __arraycount(memsetfn); i++) { 68 1.5 riastrad (void)(*memsetfn[i].fn)(buf, 0, sizeof(buf)); 69 1.5 riastrad ATF_CHECK_MSG(check(buf, sizeof(buf), 0), 70 1.5 riastrad "%s did not fill a static buffer", 71 1.5 riastrad memsetfn[i].name); 72 1.5 riastrad 73 1.5 riastrad (void)(*memsetfn[i].fn)(buf, 'x', sizeof(buf)); 74 1.5 riastrad ATF_CHECK_MSG(check(buf, sizeof(buf), 'x'), 75 1.5 riastrad "%s did not fill a static buffer", 76 1.5 riastrad memsetfn[i].name); 77 1.5 riastrad } 78 1.1 jruoho } 79 1.1 jruoho 80 1.3 christos ATF_TC(memset_return); 81 1.3 christos ATF_TC_HEAD(memset_return, tc) 82 1.3 christos { 83 1.3 christos atf_tc_set_md_var(tc, "descr", "Test memset(3) return value"); 84 1.3 christos } 85 1.3 christos 86 1.3 christos ATF_TC_BODY(memset_return, tc) 87 1.3 christos { 88 1.3 christos char *b = (char *)0x1; 89 1.3 christos char c[2]; 90 1.5 riastrad char *p; 91 1.5 riastrad unsigned i; 92 1.5 riastrad 93 1.5 riastrad for (i = 0; i < __arraycount(memsetfn); i++) { 94 1.5 riastrad ATF_CHECK_EQ_MSG((p = (*memsetfn[i].fn)(b, 0, 0)), b, 95 1.5 riastrad "%s: returned %p, expected %p", memsetfn[i].name, p, b); 96 1.5 riastrad ATF_CHECK_EQ_MSG((p = (*memsetfn[i].fn)(c, 2, sizeof(c))), c, 97 1.5 riastrad "%s: returned %p, expected %p", memsetfn[i].name, p, c); 98 1.5 riastrad } 99 1.3 christos } 100 1.3 christos 101 1.1 jruoho ATF_TC(memset_basic); 102 1.1 jruoho ATF_TC_HEAD(memset_basic, tc) 103 1.1 jruoho { 104 1.1 jruoho atf_tc_set_md_var(tc, "descr", "A basic test of memset(3)"); 105 1.1 jruoho } 106 1.1 jruoho 107 1.1 jruoho ATF_TC_BODY(memset_basic, tc) 108 1.1 jruoho { 109 1.1 jruoho char *buf, *ret; 110 1.5 riastrad unsigned i; 111 1.1 jruoho 112 1.1 jruoho buf = malloc(page); 113 1.1 jruoho ret = malloc(page); 114 1.1 jruoho 115 1.1 jruoho ATF_REQUIRE(buf != NULL); 116 1.1 jruoho ATF_REQUIRE(ret != NULL); 117 1.1 jruoho 118 1.5 riastrad for (i = 0; i < __arraycount(memsetfn); i++) { 119 1.5 riastrad fill(ret, page, 0); 120 1.5 riastrad (*memsetfn[i].fn)(buf, 0, page); 121 1.1 jruoho 122 1.5 riastrad ATF_CHECK_EQ_MSG(memcmp(ret, buf, page), 0, "%s", 123 1.5 riastrad memsetfn[i].name); 124 1.1 jruoho 125 1.5 riastrad fill(ret, page, 'x'); 126 1.5 riastrad (*memsetfn[i].fn)(buf, 'x', page); 127 1.1 jruoho 128 1.5 riastrad ATF_CHECK_EQ_MSG(memcmp(ret, buf, page), 0, "%s", 129 1.5 riastrad memsetfn[i].name); 130 1.5 riastrad } 131 1.1 jruoho 132 1.1 jruoho free(buf); 133 1.1 jruoho free(ret); 134 1.1 jruoho } 135 1.1 jruoho 136 1.1 jruoho ATF_TC(memset_nonzero); 137 1.1 jruoho ATF_TC_HEAD(memset_nonzero, tc) 138 1.1 jruoho { 139 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test memset(3) with non-zero params"); 140 1.1 jruoho } 141 1.1 jruoho 142 1.1 jruoho ATF_TC_BODY(memset_nonzero, tc) 143 1.1 jruoho { 144 1.1 jruoho const size_t n = 0x7f; 145 1.1 jruoho char *buf; 146 1.5 riastrad size_t i, j; 147 1.1 jruoho 148 1.1 jruoho buf = malloc(page); 149 1.1 jruoho ATF_REQUIRE(buf != NULL); 150 1.1 jruoho 151 1.1 jruoho for (i = 0x21; i < n; i++) { 152 1.5 riastrad for (j = 0; j < __arraycount(memsetfn); j++) { 153 1.5 riastrad (void)(*memsetfn[j].fn)(buf, i, page); 154 1.5 riastrad ATF_CHECK_MSG(check(buf, page, i), 155 1.5 riastrad "%s did not fill properly with %zu", 156 1.5 riastrad memsetfn[j].name, i); 157 1.5 riastrad } 158 1.1 jruoho } 159 1.1 jruoho 160 1.1 jruoho free(buf); 161 1.1 jruoho } 162 1.1 jruoho 163 1.4 martin ATF_TC(memset_zero_size); 164 1.4 martin 165 1.4 martin ATF_TC_HEAD(memset_zero_size, tc) 166 1.4 martin { 167 1.4 martin atf_tc_set_md_var(tc, "descr", "Test memset(3) with zero size"); 168 1.4 martin } 169 1.4 martin 170 1.4 martin ATF_TC_BODY(memset_zero_size, tc) 171 1.4 martin { 172 1.4 martin char buf[1024]; 173 1.5 riastrad unsigned i; 174 1.4 martin 175 1.5 riastrad for (i = 0; i < __arraycount(memsetfn); i++) { 176 1.5 riastrad (void)(*memsetfn[i].fn)(buf, 'x', sizeof(buf)); 177 1.5 riastrad ATF_CHECK_MSG(check(buf, sizeof(buf), 'x'), 178 1.5 riastrad "%s did not fill a static buffer", 179 1.5 riastrad memsetfn[i].name); 180 1.5 riastrad 181 1.5 riastrad (void)memset(buf+sizeof(buf)/2, 0, zero); 182 1.5 riastrad ATF_CHECK_MSG(check(buf, sizeof(buf), 'x'), 183 1.5 riastrad "%s with 0 size did change the buffer", 184 1.5 riastrad memsetfn[i].name); 185 1.5 riastrad } 186 1.4 martin } 187 1.4 martin 188 1.4 martin ATF_TC(bzero_zero_size); 189 1.4 martin 190 1.4 martin ATF_TC_HEAD(bzero_zero_size, tc) 191 1.4 martin { 192 1.4 martin atf_tc_set_md_var(tc, "descr", "Test bzero(3) with zero size"); 193 1.4 martin } 194 1.4 martin 195 1.4 martin ATF_TC_BODY(bzero_zero_size, tc) 196 1.4 martin { 197 1.4 martin char buf[1024]; 198 1.4 martin 199 1.4 martin (void)memset(buf, 'x', sizeof(buf)); 200 1.4 martin 201 1.4 martin if (check(buf, sizeof(buf), 'x') != true) 202 1.4 martin atf_tc_fail("memset(3) did not fill a static buffer"); 203 1.4 martin 204 1.4 martin (void)bzero(buf+sizeof(buf)/2, zero); 205 1.4 martin 206 1.4 martin if (check(buf, sizeof(buf), 'x') != true) 207 1.4 martin atf_tc_fail("bzero(3) with 0 size did change the buffer"); 208 1.4 martin } 209 1.4 martin 210 1.1 jruoho ATF_TC(memset_struct); 211 1.1 jruoho ATF_TC_HEAD(memset_struct, tc) 212 1.1 jruoho { 213 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test memset(3) with a structure"); 214 1.1 jruoho } 215 1.1 jruoho 216 1.1 jruoho ATF_TC_BODY(memset_struct, tc) 217 1.1 jruoho { 218 1.1 jruoho struct stat st; 219 1.5 riastrad unsigned i; 220 1.1 jruoho 221 1.5 riastrad for (i = 0; i < __arraycount(memsetfn); i++) { 222 1.5 riastrad st.st_dev = 0; 223 1.5 riastrad st.st_ino = 1; 224 1.5 riastrad st.st_mode = 2; 225 1.5 riastrad st.st_nlink = 3; 226 1.5 riastrad st.st_uid = 4; 227 1.5 riastrad st.st_gid = 5; 228 1.5 riastrad st.st_rdev = 6; 229 1.5 riastrad st.st_size = 7; 230 1.5 riastrad st.st_atime = 8; 231 1.5 riastrad st.st_mtime = 9; 232 1.5 riastrad 233 1.5 riastrad (void)(*memsetfn[i].fn)(&st, 0, sizeof(struct stat)); 234 1.5 riastrad 235 1.5 riastrad ATF_CHECK_MSG(st.st_dev == 0, "%s", memsetfn[i].name); 236 1.5 riastrad ATF_CHECK_MSG(st.st_ino == 0, "%s", memsetfn[i].name); 237 1.5 riastrad ATF_CHECK_MSG(st.st_mode == 0, "%s", memsetfn[i].name); 238 1.5 riastrad ATF_CHECK_MSG(st.st_nlink == 0, "%s", memsetfn[i].name); 239 1.5 riastrad ATF_CHECK_MSG(st.st_uid == 0, "%s", memsetfn[i].name); 240 1.5 riastrad ATF_CHECK_MSG(st.st_gid == 0, "%s", memsetfn[i].name); 241 1.5 riastrad ATF_CHECK_MSG(st.st_rdev == 0, "%s", memsetfn[i].name); 242 1.5 riastrad ATF_CHECK_MSG(st.st_size == 0, "%s", memsetfn[i].name); 243 1.5 riastrad ATF_CHECK_MSG(st.st_atime == 0, "%s", memsetfn[i].name); 244 1.5 riastrad ATF_CHECK_MSG(st.st_mtime == 0, "%s", memsetfn[i].name); 245 1.5 riastrad } 246 1.1 jruoho } 247 1.1 jruoho 248 1.1 jruoho static void 249 1.1 jruoho fill(char *buf, size_t len, char x) 250 1.1 jruoho { 251 1.1 jruoho size_t i; 252 1.1 jruoho 253 1.1 jruoho for (i = 0; i < len; i++) 254 1.1 jruoho buf[i] = x; 255 1.1 jruoho } 256 1.1 jruoho 257 1.1 jruoho static bool 258 1.1 jruoho check(char *buf, size_t len, char x) 259 1.1 jruoho { 260 1.1 jruoho size_t i; 261 1.1 jruoho 262 1.1 jruoho for (i = 0; i < len; i++) { 263 1.1 jruoho 264 1.1 jruoho if (buf[i] != x) 265 1.1 jruoho return false; 266 1.1 jruoho } 267 1.1 jruoho 268 1.1 jruoho return true; 269 1.1 jruoho } 270 1.1 jruoho 271 1.1 jruoho ATF_TP_ADD_TCS(tp) 272 1.1 jruoho { 273 1.1 jruoho 274 1.1 jruoho page = sysconf(_SC_PAGESIZE); 275 1.1 jruoho ATF_REQUIRE(page >= 0); 276 1.1 jruoho 277 1.1 jruoho ATF_TP_ADD_TC(tp, memset_array); 278 1.1 jruoho ATF_TP_ADD_TC(tp, memset_basic); 279 1.1 jruoho ATF_TP_ADD_TC(tp, memset_nonzero); 280 1.1 jruoho ATF_TP_ADD_TC(tp, memset_struct); 281 1.3 christos ATF_TP_ADD_TC(tp, memset_return); 282 1.4 martin ATF_TP_ADD_TC(tp, memset_zero_size); 283 1.4 martin ATF_TP_ADD_TC(tp, bzero_zero_size); 284 1.1 jruoho 285 1.1 jruoho return atf_no_error(); 286 1.1 jruoho } 287