Wed Jul 1 05:37:25 2020 UTC ()
Add basic tests for the rest of the mktemp(3) family of functions, including
a case for PR lib/55441.


(jruoho)
diff -r1.1 -r1.2 src/tests/lib/libc/stdlib/t_mktemp.c

cvs diff -r1.1 -r1.2 src/tests/lib/libc/stdlib/t_mktemp.c (expand / switch to unified diff)

--- src/tests/lib/libc/stdlib/t_mktemp.c 2020/06/27 09:45:57 1.1
+++ src/tests/lib/libc/stdlib/t_mktemp.c 2020/07/01 05:37:25 1.2
@@ -1,54 +1,266 @@ @@ -1,54 +1,266 @@
1/* $NetBSD: t_mktemp.c,v 1.1 2020/06/27 09:45:57 jruoho Exp $ */ 1/* $NetBSD: t_mktemp.c,v 1.2 2020/07/01 05:37:25 jruoho Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2013 The NetBSD Foundation, Inc. 4 * Copyright (c) 2013, 2020 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas. 8 * by Christos Zoulas and Jukka Ruohonen.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__RCSID("$NetBSD: t_mktemp.c,v 1.1 2020/06/27 09:45:57 jruoho Exp $"); 32__RCSID("$NetBSD: t_mktemp.c,v 1.2 2020/07/01 05:37:25 jruoho Exp $");
 33
 34#include <sys/stat.h>
33 35
34#include <atf-c.h> 36#include <atf-c.h>
 37#include <fcntl.h>
 38#include <limits.h>
 39#include <stdio.h>
35#include <stdlib.h> 40#include <stdlib.h>
 41#include <unistd.h>
 42
 43static int
 44check_mode(struct stat sa, const int mode, const int dir)
 45{
 46
 47 if (dir == 0 && S_ISREG(sa.st_mode) == 0)
 48 return -1;
 49
 50 if (dir != 0 && S_ISDIR(sa.st_mode) == 0)
 51 return -1;
 52
 53 if ((sa.st_mode & mode) == 0)
 54 return -1;
 55
 56 return 0;
 57}
36 58
37ATF_TC(mktemp_not_exist); 59ATF_TC(mktemp_not_exist);
38ATF_TC_HEAD(mktemp_not_exist, tc) 60ATF_TC_HEAD(mktemp_not_exist, tc)
39{ 61{
40 atf_tc_set_md_var(tc, "descr", "Test that mktemp does not fail on" 62 atf_tc_set_md_var(tc, "descr", "Test that mktemp(3)"
41 " a path that does not exist"); 63 " does not fail on a path that does not exist");
42} 64}
43 65
44ATF_TC_BODY(mktemp_not_exist, tc) 66ATF_TC_BODY(mktemp_not_exist, tc)
45{ 67{
46 char template[] = "I will barf/XXXXXX"; 68 char template[] = "I will barf/XXXXXX";
47 ATF_REQUIRE(mktemp(template) != NULL); 69 ATF_REQUIRE(mktemp(template) != NULL);
48} 70}
49 71
 72ATF_TC(mktemp_large_template);
 73ATF_TC_HEAD(mktemp_large_template, tc)
 74{
 75 atf_tc_set_md_var(tc, "descr", "Test that mktemp "
 76 "accepts arbitrarily large templates (PR lib/55441)");
 77}
 78
 79ATF_TC_BODY(mktemp_large_template, tc)
 80{
 81 const char *path = "/tmp/mktemp.XXXXXX";
 82 char template[PATH_MAX] = { 0 };
 83 size_t i;
 84
 85 atf_tc_expect_fail("PR lib/55441");
 86
 87 ATF_REQUIRE(strcpy(template, path) != NULL);
 88 ATF_REQUIRE(mktemp(template) != NULL);
 89 ATF_REQUIRE(strlen(template) == strlen(path));
 90 ATF_REQUIRE(strcmp(template, path) != 0);
 91 ATF_REQUIRE(strncmp(template, "/tmp/mktemp.", 12) == 0);
 92
 93 (void)memset(template, '\0', sizeof(template));
 94 (void)strcpy(template, "/tmp/mktemp.");
 95
 96 for (i = 12; i < sizeof(template) - 1; i++)
 97 template[i] = 'X';
 98
 99 ATF_REQUIRE(mktemp(template) != NULL);
 100 ATF_REQUIRE(strlen(template) == sizeof(template) - 1);
 101 ATF_REQUIRE(strcmp(template, path) != 0);
 102 ATF_REQUIRE(strncmp(template, "/tmp/mktemp.", 12) == 0);
 103}
 104
 105ATF_TC(mkstemp_basic);
 106ATF_TC_HEAD(mkstemp_basic, tc)
 107{
 108 atf_tc_set_md_var(tc, "descr", "A basic test of mkstemp(3)");
 109}
 110
 111ATF_TC_BODY(mkstemp_basic, tc)
 112{
 113 char template[] = "/tmp/mktemp.XXXXXX";
 114 struct stat sa;
 115 int fd;
 116
 117 (void)memset(&sa, 0, sizeof(struct stat));
 118
 119 fd = mkstemp(template);
 120
 121 ATF_REQUIRE(fd != -1);
 122 ATF_REQUIRE(strncmp(template, "/tmp/mktemp.", 12) == 0);
 123 ATF_REQUIRE(write(fd, "X", 1) == 1);
 124 ATF_REQUIRE(fstat(fd, &sa) == 0);
 125 ATF_REQUIRE(check_mode(sa, 0600, 0) == 0);
 126 ATF_REQUIRE(close(fd) == 0);
 127 ATF_REQUIRE(unlink(template) == 0);
 128}
 129
 130ATF_TC(mkstemps_basic);
 131ATF_TC_HEAD(mkstemps_basic, tc)
 132{
 133 atf_tc_set_md_var(tc, "descr", "A basic test of mkstemps(3)");
 134}
 135
 136ATF_TC_BODY(mkstemps_basic, tc)
 137{
 138 char template[] = "/tmp/mktemp.XXXyyy";
 139 struct stat sa;
 140 int fd;
 141
 142 (void)memset(&sa, 0, sizeof(struct stat));
 143
 144 fd = mkstemps(template, 3);
 145
 146 ATF_REQUIRE(fd != -1);
 147 ATF_REQUIRE(strncmp(template, "/tmp/mktemp.", 12) == 0);
 148
 149 char *str = strchr(template, 'y');
 150
 151 ATF_REQUIRE(strcmp(str, "yyy") == 0);
 152 ATF_REQUIRE(write(fd, "X", 1) == 1);
 153 ATF_REQUIRE(fstat(fd, &sa) == 0);
 154 ATF_REQUIRE(check_mode(sa, 0600, 0) == 0);
 155 ATF_REQUIRE(close(fd) == 0);
 156 ATF_REQUIRE(unlink(template) == 0);
 157}
 158
 159ATF_TC(mkdtemp_basic);
 160ATF_TC_HEAD(mkdtemp_basic, tc)
 161{
 162 atf_tc_set_md_var(tc, "descr", "A basic test of mkdtemp(3)");
 163}
 164
 165ATF_TC_BODY(mkdtemp_basic, tc)
 166{
 167 char template[] = "/tmp/mktemp.XXXXXX";
 168 char *path = mkdtemp(template);
 169 struct stat sa;
 170
 171 (void)memset(&sa, 0, sizeof(struct stat));
 172
 173 ATF_REQUIRE(path != NULL);
 174 ATF_REQUIRE(strncmp(template, "/tmp/mktemp.", 12) == 0);
 175 ATF_REQUIRE(stat(path, &sa) == 0);
 176 ATF_REQUIRE(check_mode(sa, 0700, 1) == 0);
 177 ATF_REQUIRE(rmdir(path) == 0);
 178}
 179
 180ATF_TC(mkostemp_basic);
 181ATF_TC_HEAD(mkostemp_basic, tc)
 182{
 183 atf_tc_set_md_var(tc, "descr", "A basic test of mkostemp(3)");
 184}
 185
 186ATF_TC_BODY(mkostemp_basic, tc)
 187{
 188 static const int flags[] = {
 189 O_APPEND, O_DIRECT,
 190 O_SHLOCK, O_EXLOCK,
 191 O_SYNC, O_CLOEXEC
 192 };
 193
 194 char template[] = "/tmp/mktemp.XXXXXX";
 195 struct stat sa;
 196 size_t i;
 197 int fd;
 198
 199 for (i = 0; i < __arraycount(flags); i++) {
 200
 201 (void)memset(&sa, 0, sizeof(struct stat));
 202
 203 fd = mkostemp(template, flags[i]);
 204
 205 ATF_REQUIRE(fd != -1);
 206 ATF_REQUIRE(strncmp(template, "/tmp/mktemp.", 12) == 0);
 207 ATF_REQUIRE(write(fd, "X", 1) == 1);
 208 ATF_REQUIRE(fstat(fd, &sa) == 0);
 209 ATF_REQUIRE(check_mode(sa, 0600 | flags[i], 0) == 0);
 210 ATF_REQUIRE(close(fd) == 0);
 211 ATF_REQUIRE(unlink(template) == 0);
 212 }
 213}
 214
 215ATF_TC(mkostemps_basic);
 216ATF_TC_HEAD(mkostemps_basic, tc)
 217{
 218 atf_tc_set_md_var(tc, "descr", "A basic test of mkostemps(3)");
 219}
 220
 221ATF_TC_BODY(mkostemps_basic, tc)
 222{
 223 static const int flags[] = {
 224 O_APPEND, O_DIRECT,
 225 O_SHLOCK, O_EXLOCK,
 226 O_SYNC, O_CLOEXEC
 227 };
 228
 229 char template[] = "/tmp/mktemp.XXXyyy";
 230 struct stat sa;
 231 size_t i;
 232 int fd;
 233
 234 for (i = 0; i < __arraycount(flags); i++) {
 235
 236 (void)memset(&sa, 0, sizeof(struct stat));
 237
 238 fd = mkostemps(template, 3, flags[i]);
 239
 240 ATF_REQUIRE(fd != -1);
 241 ATF_REQUIRE(strncmp(template, "/tmp/mktemp.", 12) == 0);
 242
 243 char *str = strchr(template, 'y');
 244
 245 ATF_REQUIRE(strcmp(str, "yyy") == 0);
 246 ATF_REQUIRE(write(fd, "X", 1) == 1);
 247 ATF_REQUIRE(fstat(fd, &sa) == 0);
 248 ATF_REQUIRE(check_mode(sa, 0600 | flags[i], 0) == 0);
 249 ATF_REQUIRE(close(fd) == 0);
 250 ATF_REQUIRE(unlink(template) == 0);
 251 }
 252}
 253
50ATF_TP_ADD_TCS(tp) 254ATF_TP_ADD_TCS(tp)
51{ 255{
 256
52 ATF_TP_ADD_TC(tp, mktemp_not_exist); 257 ATF_TP_ADD_TC(tp, mktemp_not_exist);
 258 ATF_TP_ADD_TC(tp, mktemp_large_template);
 259 ATF_TP_ADD_TC(tp, mkstemp_basic);
 260 ATF_TP_ADD_TC(tp, mkstemps_basic);
 261 ATF_TP_ADD_TC(tp, mkdtemp_basic);
 262 ATF_TP_ADD_TC(tp, mkostemp_basic);
 263 ATF_TP_ADD_TC(tp, mkostemps_basic);
 264
53 return atf_no_error(); 265 return atf_no_error();
54} 266}