1*760d825bSanton /* $OpenBSD: t_truncate.c,v 1.4 2022/05/24 05:14:30 anton Exp $ */
2a545a52cSbluhm /* $NetBSD: t_truncate.c,v 1.3 2017/01/13 20:03:51 christos Exp $ */
3a545a52cSbluhm
4a545a52cSbluhm /*-
5a545a52cSbluhm * Copyright (c) 2011 The NetBSD Foundation, Inc.
6a545a52cSbluhm * All rights reserved.
7a545a52cSbluhm *
8a545a52cSbluhm * This code is derived from software contributed to The NetBSD Foundation
9a545a52cSbluhm * by Jukka Ruohonen.
10a545a52cSbluhm *
11a545a52cSbluhm * Redistribution and use in source and binary forms, with or without
12a545a52cSbluhm * modification, are permitted provided that the following conditions
13a545a52cSbluhm * are met:
14a545a52cSbluhm * 1. Redistributions of source code must retain the above copyright
15a545a52cSbluhm * notice, this list of conditions and the following disclaimer.
16a545a52cSbluhm * 2. Redistributions in binary form must reproduce the above copyright
17a545a52cSbluhm * notice, this list of conditions and the following disclaimer in the
18a545a52cSbluhm * documentation and/or other materials provided with the distribution.
19a545a52cSbluhm *
20a545a52cSbluhm * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21a545a52cSbluhm * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22a545a52cSbluhm * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23a545a52cSbluhm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24a545a52cSbluhm * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25a545a52cSbluhm * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26a545a52cSbluhm * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27a545a52cSbluhm * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28a545a52cSbluhm * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29a545a52cSbluhm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30a545a52cSbluhm * POSSIBILITY OF SUCH DAMAGE.
31a545a52cSbluhm */
32a545a52cSbluhm
33a545a52cSbluhm #include "macros.h"
34a545a52cSbluhm
35a545a52cSbluhm #include <sys/stat.h>
36a545a52cSbluhm
37a545a52cSbluhm #include "atf-c.h"
38a545a52cSbluhm #include <errno.h>
39a545a52cSbluhm #include <fcntl.h>
40a545a52cSbluhm #include <limits.h>
41a545a52cSbluhm #include <stdio.h>
42a545a52cSbluhm #include <string.h>
43a545a52cSbluhm #include <unistd.h>
44a545a52cSbluhm
45a545a52cSbluhm static const char path[] = "truncate";
46a545a52cSbluhm static const size_t sizes[] = { 8, 16, 512, 1024, 2048, 4094, 3000, 30 };
47a545a52cSbluhm
48a545a52cSbluhm ATF_TC_WITH_CLEANUP(ftruncate_basic);
ATF_TC_HEAD(ftruncate_basic,tc)49a545a52cSbluhm ATF_TC_HEAD(ftruncate_basic, tc)
50a545a52cSbluhm {
51a545a52cSbluhm atf_tc_set_md_var(tc, "descr", "A basic test of ftruncate(2)");
52a545a52cSbluhm }
53a545a52cSbluhm
ATF_TC_BODY(ftruncate_basic,tc)54a545a52cSbluhm ATF_TC_BODY(ftruncate_basic, tc)
55a545a52cSbluhm {
56a545a52cSbluhm struct stat st;
57a545a52cSbluhm size_t i;
58a545a52cSbluhm int fd;
59a545a52cSbluhm
60a545a52cSbluhm fd = open(path, O_RDWR | O_CREAT, 0600);
61a545a52cSbluhm ATF_REQUIRE(fd >= 0);
62a545a52cSbluhm
63a545a52cSbluhm for (i = 0; i < __arraycount(sizes); i++) {
64a545a52cSbluhm
65a545a52cSbluhm (void)memset(&st, 0, sizeof(struct stat));
66a545a52cSbluhm
67a545a52cSbluhm ATF_REQUIRE(ftruncate(fd, sizes[i]) == 0);
68a545a52cSbluhm ATF_REQUIRE(fstat(fd, &st) == 0);
69a545a52cSbluhm
70a545a52cSbluhm (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]);
71a545a52cSbluhm
72a545a52cSbluhm if (sizes[i] != (size_t)st.st_size)
73a545a52cSbluhm atf_tc_fail("ftruncate(2) did not truncate");
74a545a52cSbluhm }
75a545a52cSbluhm
76a545a52cSbluhm (void)close(fd);
77a545a52cSbluhm (void)unlink(path);
78a545a52cSbluhm }
79a545a52cSbluhm
ATF_TC_CLEANUP(ftruncate_basic,tc)80a545a52cSbluhm ATF_TC_CLEANUP(ftruncate_basic, tc)
81a545a52cSbluhm {
82a545a52cSbluhm (void)unlink(path);
83a545a52cSbluhm }
84a545a52cSbluhm
85a545a52cSbluhm ATF_TC(ftruncate_err);
ATF_TC_HEAD(ftruncate_err,tc)86a545a52cSbluhm ATF_TC_HEAD(ftruncate_err, tc)
87a545a52cSbluhm {
88a545a52cSbluhm atf_tc_set_md_var(tc, "descr", "Test errors from ftruncate(2)");
89a545a52cSbluhm atf_tc_set_md_var(tc, "require.user", "unprivileged");
90a545a52cSbluhm }
91a545a52cSbluhm
ATF_TC_BODY(ftruncate_err,tc)92a545a52cSbluhm ATF_TC_BODY(ftruncate_err, tc)
93a545a52cSbluhm {
94a545a52cSbluhm int fd;
95a545a52cSbluhm
96b7041c07Sderaadt fd = open("/etc/passwd", O_RDONLY);
97a545a52cSbluhm ATF_REQUIRE(fd >= 0);
98a545a52cSbluhm
99a545a52cSbluhm errno = 0;
100a545a52cSbluhm ATF_REQUIRE_ERRNO(EBADF, ftruncate(-1, 999) == -1);
101a545a52cSbluhm
102a545a52cSbluhm errno = 0;
103a545a52cSbluhm ATF_REQUIRE_ERRNO(EINVAL, ftruncate(fd, 999) == -1);
104a545a52cSbluhm
105a545a52cSbluhm (void)close(fd);
106a545a52cSbluhm }
107a545a52cSbluhm
108a545a52cSbluhm ATF_TC_WITH_CLEANUP(truncate_basic);
ATF_TC_HEAD(truncate_basic,tc)109a545a52cSbluhm ATF_TC_HEAD(truncate_basic, tc)
110a545a52cSbluhm {
111a545a52cSbluhm atf_tc_set_md_var(tc, "descr", "A basic test of truncate(2)");
112a545a52cSbluhm }
113a545a52cSbluhm
ATF_TC_BODY(truncate_basic,tc)114a545a52cSbluhm ATF_TC_BODY(truncate_basic, tc)
115a545a52cSbluhm {
116a545a52cSbluhm struct stat st;
117a545a52cSbluhm size_t i;
118a545a52cSbluhm int fd;
119a545a52cSbluhm
120a545a52cSbluhm fd = open(path, O_RDWR | O_CREAT, 0600);
121a545a52cSbluhm ATF_REQUIRE(fd >= 0);
122a545a52cSbluhm
123a545a52cSbluhm for (i = 0; i < __arraycount(sizes); i++) {
124a545a52cSbluhm
125a545a52cSbluhm (void)memset(&st, 0, sizeof(struct stat));
126a545a52cSbluhm
127a545a52cSbluhm ATF_REQUIRE(truncate(path, sizes[i]) == 0);
128a545a52cSbluhm ATF_REQUIRE(fstat(fd, &st) == 0);
129a545a52cSbluhm
130a545a52cSbluhm (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]);
131a545a52cSbluhm
132a545a52cSbluhm if (sizes[i] != (size_t)st.st_size)
133a545a52cSbluhm atf_tc_fail("truncate(2) did not truncate");
134a545a52cSbluhm }
135a545a52cSbluhm
136a545a52cSbluhm (void)close(fd);
137a545a52cSbluhm (void)unlink(path);
138a545a52cSbluhm }
139a545a52cSbluhm
ATF_TC_CLEANUP(truncate_basic,tc)140a545a52cSbluhm ATF_TC_CLEANUP(truncate_basic, tc)
141a545a52cSbluhm {
142a545a52cSbluhm (void)unlink(path);
143a545a52cSbluhm }
144a545a52cSbluhm
145a545a52cSbluhm ATF_TC(truncate_err);
ATF_TC_HEAD(truncate_err,tc)146a545a52cSbluhm ATF_TC_HEAD(truncate_err, tc)
147a545a52cSbluhm {
148a545a52cSbluhm atf_tc_set_md_var(tc, "descr", "Test errors from truncate(2)");
149a545a52cSbluhm atf_tc_set_md_var(tc, "require.user", "unprivileged");
150a545a52cSbluhm }
151a545a52cSbluhm
ATF_TC_BODY(truncate_err,tc)152a545a52cSbluhm ATF_TC_BODY(truncate_err, tc)
153a545a52cSbluhm {
154a545a52cSbluhm char buf[PATH_MAX];
155a545a52cSbluhm
156a545a52cSbluhm errno = 0;
157a545a52cSbluhm ATF_REQUIRE_ERRNO(EFAULT, truncate((void *)-1, 999) == -1);
158a545a52cSbluhm
159a545a52cSbluhm errno = 0;
160*760d825bSanton ATF_REQUIRE_ERRNO(EISDIR, truncate("/tmp", 999) == -1);
161a545a52cSbluhm
162a545a52cSbluhm errno = 0;
163a545a52cSbluhm ATF_REQUIRE_ERRNO(ENOENT, truncate("/a/b/c/d/e/f/g", 999) == -1);
164a545a52cSbluhm
165a545a52cSbluhm errno = 0;
166a545a52cSbluhm snprintf(buf, sizeof(buf), "%s/truncate_test.root_owned",
167a545a52cSbluhm atf_tc_get_config_var(tc, "srcdir"));
168a545a52cSbluhm ATF_REQUIRE_ERRNO(EACCES, truncate(buf, 999) == -1);
169a545a52cSbluhm }
170a545a52cSbluhm
ATF_TP_ADD_TCS(tp)171a545a52cSbluhm ATF_TP_ADD_TCS(tp)
172a545a52cSbluhm {
173a545a52cSbluhm
174a545a52cSbluhm ATF_TP_ADD_TC(tp, ftruncate_basic);
175a545a52cSbluhm ATF_TP_ADD_TC(tp, ftruncate_err);
176a545a52cSbluhm ATF_TP_ADD_TC(tp, truncate_basic);
177a545a52cSbluhm ATF_TP_ADD_TC(tp, truncate_err);
178a545a52cSbluhm
179a545a52cSbluhm return atf_no_error();
180a545a52cSbluhm }
181