| @@ -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 | |
| | | 43 | static int |
| | | 44 | check_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 | |
37 | ATF_TC(mktemp_not_exist); | | 59 | ATF_TC(mktemp_not_exist); |
38 | ATF_TC_HEAD(mktemp_not_exist, tc) | | 60 | ATF_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 | |
44 | ATF_TC_BODY(mktemp_not_exist, tc) | | 66 | ATF_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 | |
| | | 72 | ATF_TC(mktemp_large_template); |
| | | 73 | ATF_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 | |
| | | 79 | ATF_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 | |
| | | 105 | ATF_TC(mkstemp_basic); |
| | | 106 | ATF_TC_HEAD(mkstemp_basic, tc) |
| | | 107 | { |
| | | 108 | atf_tc_set_md_var(tc, "descr", "A basic test of mkstemp(3)"); |
| | | 109 | } |
| | | 110 | |
| | | 111 | ATF_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 | |
| | | 130 | ATF_TC(mkstemps_basic); |
| | | 131 | ATF_TC_HEAD(mkstemps_basic, tc) |
| | | 132 | { |
| | | 133 | atf_tc_set_md_var(tc, "descr", "A basic test of mkstemps(3)"); |
| | | 134 | } |
| | | 135 | |
| | | 136 | ATF_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 | |
| | | 159 | ATF_TC(mkdtemp_basic); |
| | | 160 | ATF_TC_HEAD(mkdtemp_basic, tc) |
| | | 161 | { |
| | | 162 | atf_tc_set_md_var(tc, "descr", "A basic test of mkdtemp(3)"); |
| | | 163 | } |
| | | 164 | |
| | | 165 | ATF_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 | |
| | | 180 | ATF_TC(mkostemp_basic); |
| | | 181 | ATF_TC_HEAD(mkostemp_basic, tc) |
| | | 182 | { |
| | | 183 | atf_tc_set_md_var(tc, "descr", "A basic test of mkostemp(3)"); |
| | | 184 | } |
| | | 185 | |
| | | 186 | ATF_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 | |
| | | 215 | ATF_TC(mkostemps_basic); |
| | | 216 | ATF_TC_HEAD(mkostemps_basic, tc) |
| | | 217 | { |
| | | 218 | atf_tc_set_md_var(tc, "descr", "A basic test of mkostemps(3)"); |
| | | 219 | } |
| | | 220 | |
| | | 221 | ATF_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 | |
50 | ATF_TP_ADD_TCS(tp) | | 254 | ATF_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 | } |