1*d25fab54Schristos /* $NetBSD: t_mktemp.c,v 1.4 2021/01/11 20:31:34 christos Exp $ */
2f60c53b4Sjruoho
3f60c53b4Sjruoho /*-
47fed5435Sjruoho * Copyright (c) 2013, 2020 The NetBSD Foundation, Inc.
5f60c53b4Sjruoho * All rights reserved.
6f60c53b4Sjruoho *
7f60c53b4Sjruoho * This code is derived from software contributed to The NetBSD Foundation
87fed5435Sjruoho * by Christos Zoulas and Jukka Ruohonen.
9f60c53b4Sjruoho *
10f60c53b4Sjruoho * Redistribution and use in source and binary forms, with or without
11f60c53b4Sjruoho * modification, are permitted provided that the following conditions
12f60c53b4Sjruoho * are met:
13f60c53b4Sjruoho * 1. Redistributions of source code must retain the above copyright
14f60c53b4Sjruoho * notice, this list of conditions and the following disclaimer.
15f60c53b4Sjruoho * 2. Redistributions in binary form must reproduce the above copyright
16f60c53b4Sjruoho * notice, this list of conditions and the following disclaimer in the
17f60c53b4Sjruoho * documentation and/or other materials provided with the distribution.
18f60c53b4Sjruoho *
19f60c53b4Sjruoho * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20f60c53b4Sjruoho * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21f60c53b4Sjruoho * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22f60c53b4Sjruoho * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23f60c53b4Sjruoho * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24f60c53b4Sjruoho * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25f60c53b4Sjruoho * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26f60c53b4Sjruoho * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27f60c53b4Sjruoho * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28f60c53b4Sjruoho * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29f60c53b4Sjruoho * POSSIBILITY OF SUCH DAMAGE.
30f60c53b4Sjruoho */
31f60c53b4Sjruoho #include <sys/cdefs.h>
32*d25fab54Schristos __RCSID("$NetBSD: t_mktemp.c,v 1.4 2021/01/11 20:31:34 christos Exp $");
337fed5435Sjruoho
347fed5435Sjruoho #include <sys/stat.h>
35f60c53b4Sjruoho
36f60c53b4Sjruoho #include <atf-c.h>
377fed5435Sjruoho #include <fcntl.h>
387fed5435Sjruoho #include <limits.h>
397fed5435Sjruoho #include <stdio.h>
40f60c53b4Sjruoho #include <stdlib.h>
417fed5435Sjruoho #include <unistd.h>
427fed5435Sjruoho
437fed5435Sjruoho static int
check_mode(struct stat sa,const int mode,const int dir)447fed5435Sjruoho check_mode(struct stat sa, const int mode, const int dir)
457fed5435Sjruoho {
467fed5435Sjruoho
477fed5435Sjruoho if (dir == 0 && S_ISREG(sa.st_mode) == 0)
487fed5435Sjruoho return -1;
497fed5435Sjruoho
507fed5435Sjruoho if (dir != 0 && S_ISDIR(sa.st_mode) == 0)
517fed5435Sjruoho return -1;
527fed5435Sjruoho
537fed5435Sjruoho if ((sa.st_mode & mode) == 0)
547fed5435Sjruoho return -1;
557fed5435Sjruoho
567fed5435Sjruoho return 0;
577fed5435Sjruoho }
58f60c53b4Sjruoho
59f60c53b4Sjruoho ATF_TC(mktemp_not_exist);
ATF_TC_HEAD(mktemp_not_exist,tc)60f60c53b4Sjruoho ATF_TC_HEAD(mktemp_not_exist, tc)
61f60c53b4Sjruoho {
627fed5435Sjruoho atf_tc_set_md_var(tc, "descr", "Test that mktemp(3)"
637fed5435Sjruoho " does not fail on a path that does not exist");
64f60c53b4Sjruoho }
65f60c53b4Sjruoho
ATF_TC_BODY(mktemp_not_exist,tc)66f60c53b4Sjruoho ATF_TC_BODY(mktemp_not_exist, tc)
67f60c53b4Sjruoho {
68f60c53b4Sjruoho char template[] = "I will barf/XXXXXX";
69f60c53b4Sjruoho ATF_REQUIRE(mktemp(template) != NULL);
70f60c53b4Sjruoho }
71f60c53b4Sjruoho
727fed5435Sjruoho ATF_TC(mktemp_large_template);
ATF_TC_HEAD(mktemp_large_template,tc)737fed5435Sjruoho ATF_TC_HEAD(mktemp_large_template, tc)
747fed5435Sjruoho {
757fed5435Sjruoho atf_tc_set_md_var(tc, "descr", "Test that mktemp "
767fed5435Sjruoho "accepts arbitrarily large templates (PR lib/55441)");
777fed5435Sjruoho }
787fed5435Sjruoho
ATF_TC_BODY(mktemp_large_template,tc)797fed5435Sjruoho ATF_TC_BODY(mktemp_large_template, tc)
807fed5435Sjruoho {
817fed5435Sjruoho const char *path = "/tmp/mktemp.XXXXXX";
82*d25fab54Schristos char *template;
837fed5435Sjruoho size_t i;
84*d25fab54Schristos long name_max;
85*d25fab54Schristos size_t tlen;
867fed5435Sjruoho
87*d25fab54Schristos name_max = pathconf("/tmp/", _PC_NAME_MAX);
88*d25fab54Schristos ATF_REQUIRE(name_max > 0);
89*d25fab54Schristos
90*d25fab54Schristos tlen = (size_t)name_max + sizeof("/tmp/");
91*d25fab54Schristos template = malloc(tlen);
92*d25fab54Schristos ATF_REQUIRE(template != NULL);
937fed5435Sjruoho
947fed5435Sjruoho ATF_REQUIRE(strcpy(template, path) != NULL);
957fed5435Sjruoho ATF_REQUIRE(mktemp(template) != NULL);
967fed5435Sjruoho ATF_REQUIRE(strlen(template) == strlen(path));
977fed5435Sjruoho ATF_REQUIRE(strcmp(template, path) != 0);
987fed5435Sjruoho ATF_REQUIRE(strncmp(template, "/tmp/mktemp.", 12) == 0);
997fed5435Sjruoho
100*d25fab54Schristos (void)memset(template, '\0', tlen);
1017fed5435Sjruoho (void)strcpy(template, "/tmp/mktemp.");
1027fed5435Sjruoho
103*d25fab54Schristos for (i = 12; i < tlen - 1; i++)
1047fed5435Sjruoho template[i] = 'X';
1057fed5435Sjruoho
1067fed5435Sjruoho ATF_REQUIRE(mktemp(template) != NULL);
107*d25fab54Schristos ATF_REQUIRE(strlen(template) == tlen - 1);
1087fed5435Sjruoho ATF_REQUIRE(strcmp(template, path) != 0);
1097fed5435Sjruoho ATF_REQUIRE(strncmp(template, "/tmp/mktemp.", 12) == 0);
110*d25fab54Schristos free(template);
1117fed5435Sjruoho }
1127fed5435Sjruoho
1137fed5435Sjruoho ATF_TC(mkstemp_basic);
ATF_TC_HEAD(mkstemp_basic,tc)1147fed5435Sjruoho ATF_TC_HEAD(mkstemp_basic, tc)
1157fed5435Sjruoho {
1167fed5435Sjruoho atf_tc_set_md_var(tc, "descr", "A basic test of mkstemp(3)");
1177fed5435Sjruoho }
1187fed5435Sjruoho
ATF_TC_BODY(mkstemp_basic,tc)1197fed5435Sjruoho ATF_TC_BODY(mkstemp_basic, tc)
1207fed5435Sjruoho {
1217fed5435Sjruoho char template[] = "/tmp/mktemp.XXXXXX";
1227fed5435Sjruoho struct stat sa;
1237fed5435Sjruoho int fd;
1247fed5435Sjruoho
1257fed5435Sjruoho (void)memset(&sa, 0, sizeof(struct stat));
1267fed5435Sjruoho
1277fed5435Sjruoho fd = mkstemp(template);
1287fed5435Sjruoho
1297fed5435Sjruoho ATF_REQUIRE(fd != -1);
1307fed5435Sjruoho ATF_REQUIRE(strncmp(template, "/tmp/mktemp.", 12) == 0);
1317fed5435Sjruoho ATF_REQUIRE(write(fd, "X", 1) == 1);
1327fed5435Sjruoho ATF_REQUIRE(fstat(fd, &sa) == 0);
1337fed5435Sjruoho ATF_REQUIRE(check_mode(sa, 0600, 0) == 0);
1347fed5435Sjruoho ATF_REQUIRE(close(fd) == 0);
1357fed5435Sjruoho ATF_REQUIRE(unlink(template) == 0);
1367fed5435Sjruoho }
1377fed5435Sjruoho
1387fed5435Sjruoho ATF_TC(mkstemps_basic);
ATF_TC_HEAD(mkstemps_basic,tc)1397fed5435Sjruoho ATF_TC_HEAD(mkstemps_basic, tc)
1407fed5435Sjruoho {
1417fed5435Sjruoho atf_tc_set_md_var(tc, "descr", "A basic test of mkstemps(3)");
1427fed5435Sjruoho }
1437fed5435Sjruoho
ATF_TC_BODY(mkstemps_basic,tc)1447fed5435Sjruoho ATF_TC_BODY(mkstemps_basic, tc)
1457fed5435Sjruoho {
1467fed5435Sjruoho char template[] = "/tmp/mktemp.XXXyyy";
147086d077dSgson char *suffix = strchr(template, 'y');
1487fed5435Sjruoho struct stat sa;
1497fed5435Sjruoho int fd;
1507fed5435Sjruoho
1517fed5435Sjruoho (void)memset(&sa, 0, sizeof(struct stat));
1527fed5435Sjruoho
1537fed5435Sjruoho fd = mkstemps(template, 3);
1547fed5435Sjruoho
1557fed5435Sjruoho ATF_REQUIRE(fd != -1);
1567fed5435Sjruoho ATF_REQUIRE(strncmp(template, "/tmp/mktemp.", 12) == 0);
157086d077dSgson ATF_REQUIRE(strcmp(suffix, "yyy") == 0);
1587fed5435Sjruoho ATF_REQUIRE(write(fd, "X", 1) == 1);
1597fed5435Sjruoho ATF_REQUIRE(fstat(fd, &sa) == 0);
1607fed5435Sjruoho ATF_REQUIRE(check_mode(sa, 0600, 0) == 0);
1617fed5435Sjruoho ATF_REQUIRE(close(fd) == 0);
1627fed5435Sjruoho ATF_REQUIRE(unlink(template) == 0);
1637fed5435Sjruoho }
1647fed5435Sjruoho
1657fed5435Sjruoho ATF_TC(mkdtemp_basic);
ATF_TC_HEAD(mkdtemp_basic,tc)1667fed5435Sjruoho ATF_TC_HEAD(mkdtemp_basic, tc)
1677fed5435Sjruoho {
1687fed5435Sjruoho atf_tc_set_md_var(tc, "descr", "A basic test of mkdtemp(3)");
1697fed5435Sjruoho }
1707fed5435Sjruoho
ATF_TC_BODY(mkdtemp_basic,tc)1717fed5435Sjruoho ATF_TC_BODY(mkdtemp_basic, tc)
1727fed5435Sjruoho {
1737fed5435Sjruoho char template[] = "/tmp/mktemp.XXXXXX";
1747fed5435Sjruoho char *path = mkdtemp(template);
1757fed5435Sjruoho struct stat sa;
1767fed5435Sjruoho
1777fed5435Sjruoho (void)memset(&sa, 0, sizeof(struct stat));
1787fed5435Sjruoho
1797fed5435Sjruoho ATF_REQUIRE(path != NULL);
1807fed5435Sjruoho ATF_REQUIRE(strncmp(template, "/tmp/mktemp.", 12) == 0);
1817fed5435Sjruoho ATF_REQUIRE(stat(path, &sa) == 0);
1827fed5435Sjruoho ATF_REQUIRE(check_mode(sa, 0700, 1) == 0);
1837fed5435Sjruoho ATF_REQUIRE(rmdir(path) == 0);
1847fed5435Sjruoho }
1857fed5435Sjruoho
1867fed5435Sjruoho ATF_TC(mkostemp_basic);
ATF_TC_HEAD(mkostemp_basic,tc)1877fed5435Sjruoho ATF_TC_HEAD(mkostemp_basic, tc)
1887fed5435Sjruoho {
1897fed5435Sjruoho atf_tc_set_md_var(tc, "descr", "A basic test of mkostemp(3)");
1907fed5435Sjruoho }
1917fed5435Sjruoho
ATF_TC_BODY(mkostemp_basic,tc)1927fed5435Sjruoho ATF_TC_BODY(mkostemp_basic, tc)
1937fed5435Sjruoho {
1947fed5435Sjruoho static const int flags[] = {
1957fed5435Sjruoho O_APPEND, O_DIRECT,
1967fed5435Sjruoho O_SHLOCK, O_EXLOCK,
1977fed5435Sjruoho O_SYNC, O_CLOEXEC
1987fed5435Sjruoho };
1997fed5435Sjruoho
2007fed5435Sjruoho char template[] = "/tmp/mktemp.XXXXXX";
2017fed5435Sjruoho struct stat sa;
2027fed5435Sjruoho size_t i;
2037fed5435Sjruoho int fd;
2047fed5435Sjruoho
2057fed5435Sjruoho for (i = 0; i < __arraycount(flags); i++) {
2067fed5435Sjruoho
2077fed5435Sjruoho (void)memset(&sa, 0, sizeof(struct stat));
2087fed5435Sjruoho
2097fed5435Sjruoho fd = mkostemp(template, flags[i]);
2107fed5435Sjruoho
2117fed5435Sjruoho ATF_REQUIRE(fd != -1);
2127fed5435Sjruoho ATF_REQUIRE(strncmp(template, "/tmp/mktemp.", 12) == 0);
2137fed5435Sjruoho ATF_REQUIRE(write(fd, "X", 1) == 1);
2147fed5435Sjruoho ATF_REQUIRE(fstat(fd, &sa) == 0);
2157fed5435Sjruoho ATF_REQUIRE(check_mode(sa, 0600 | flags[i], 0) == 0);
2167fed5435Sjruoho ATF_REQUIRE(close(fd) == 0);
2177fed5435Sjruoho ATF_REQUIRE(unlink(template) == 0);
2187fed5435Sjruoho }
2197fed5435Sjruoho }
2207fed5435Sjruoho
2217fed5435Sjruoho ATF_TC(mkostemps_basic);
ATF_TC_HEAD(mkostemps_basic,tc)2227fed5435Sjruoho ATF_TC_HEAD(mkostemps_basic, tc)
2237fed5435Sjruoho {
2247fed5435Sjruoho atf_tc_set_md_var(tc, "descr", "A basic test of mkostemps(3)");
2257fed5435Sjruoho }
2267fed5435Sjruoho
ATF_TC_BODY(mkostemps_basic,tc)2277fed5435Sjruoho ATF_TC_BODY(mkostemps_basic, tc)
2287fed5435Sjruoho {
2297fed5435Sjruoho static const int flags[] = {
2307fed5435Sjruoho O_APPEND, O_DIRECT,
2317fed5435Sjruoho O_SHLOCK, O_EXLOCK,
2327fed5435Sjruoho O_SYNC, O_CLOEXEC
2337fed5435Sjruoho };
2347fed5435Sjruoho
2357fed5435Sjruoho char template[] = "/tmp/mktemp.XXXyyy";
236086d077dSgson char *suffix = strchr(template, 'y');
2377fed5435Sjruoho struct stat sa;
2387fed5435Sjruoho size_t i;
2397fed5435Sjruoho int fd;
2407fed5435Sjruoho
2417fed5435Sjruoho for (i = 0; i < __arraycount(flags); i++) {
2427fed5435Sjruoho
2437fed5435Sjruoho (void)memset(&sa, 0, sizeof(struct stat));
2447fed5435Sjruoho
2457fed5435Sjruoho fd = mkostemps(template, 3, flags[i]);
2467fed5435Sjruoho
2477fed5435Sjruoho ATF_REQUIRE(fd != -1);
2487fed5435Sjruoho ATF_REQUIRE(strncmp(template, "/tmp/mktemp.", 12) == 0);
249086d077dSgson ATF_REQUIRE(strcmp(suffix, "yyy") == 0);
2507fed5435Sjruoho ATF_REQUIRE(write(fd, "X", 1) == 1);
2517fed5435Sjruoho ATF_REQUIRE(fstat(fd, &sa) == 0);
2527fed5435Sjruoho ATF_REQUIRE(check_mode(sa, 0600 | flags[i], 0) == 0);
2537fed5435Sjruoho ATF_REQUIRE(close(fd) == 0);
2547fed5435Sjruoho ATF_REQUIRE(unlink(template) == 0);
2557fed5435Sjruoho }
2567fed5435Sjruoho }
2577fed5435Sjruoho
ATF_TP_ADD_TCS(tp)258f60c53b4Sjruoho ATF_TP_ADD_TCS(tp)
259f60c53b4Sjruoho {
2607fed5435Sjruoho
261f60c53b4Sjruoho ATF_TP_ADD_TC(tp, mktemp_not_exist);
2627fed5435Sjruoho ATF_TP_ADD_TC(tp, mktemp_large_template);
2637fed5435Sjruoho ATF_TP_ADD_TC(tp, mkstemp_basic);
2647fed5435Sjruoho ATF_TP_ADD_TC(tp, mkstemps_basic);
2657fed5435Sjruoho ATF_TP_ADD_TC(tp, mkdtemp_basic);
2667fed5435Sjruoho ATF_TP_ADD_TC(tp, mkostemp_basic);
2677fed5435Sjruoho ATF_TP_ADD_TC(tp, mkostemps_basic);
2687fed5435Sjruoho
269f60c53b4Sjruoho return atf_no_error();
270f60c53b4Sjruoho }
271