xref: /openbsd-src/regress/lib/libc/sys/t_truncate.c (revision 760d825b763c6a895d5f192e66fe6c4e0c789a4a)
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