1272343Sngie/* $NetBSD: t_truncate.c,v 1.2 2011/08/18 19:48:03 dholland Exp $ */ 2272343Sngie 3272343Sngie/*- 4272343Sngie * Copyright (c) 2011 The NetBSD Foundation, Inc. 5272343Sngie * All rights reserved. 6272343Sngie * 7272343Sngie * This code is derived from software contributed to The NetBSD Foundation 8272343Sngie * by Jukka Ruohonen. 9272343Sngie * 10272343Sngie * Redistribution and use in source and binary forms, with or without 11272343Sngie * modification, are permitted provided that the following conditions 12272343Sngie * are met: 13272343Sngie * 1. Redistributions of source code must retain the above copyright 14272343Sngie * notice, this list of conditions and the following disclaimer. 15272343Sngie * 2. Redistributions in binary form must reproduce the above copyright 16272343Sngie * notice, this list of conditions and the following disclaimer in the 17272343Sngie * documentation and/or other materials provided with the distribution. 18272343Sngie * 19272343Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20272343Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21272343Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22272343Sngie * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23272343Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24272343Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25272343Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26272343Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27272343Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28272343Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29272343Sngie * POSSIBILITY OF SUCH DAMAGE. 30272343Sngie */ 31272343Sngie#include <sys/cdefs.h> 32272343Sngie__RCSID("$NetBSD: t_truncate.c,v 1.2 2011/08/18 19:48:03 dholland Exp $"); 33272343Sngie 34272343Sngie#include <sys/stat.h> 35272343Sngie 36272343Sngie#include <atf-c.h> 37272343Sngie#include <errno.h> 38272343Sngie#include <fcntl.h> 39272343Sngie#include <stdio.h> 40272343Sngie#include <string.h> 41272343Sngie#include <unistd.h> 42272343Sngie 43273533Sngie#ifdef __FreeBSD__ 44273533Sngie#include <limits.h> 45273533Sngie#endif 46273533Sngie 47272343Sngiestatic const char path[] = "truncate"; 48272343Sngiestatic const size_t sizes[] = { 8, 16, 512, 1024, 2048, 4094, 3000, 30 }; 49272343Sngie 50272343SngieATF_TC_WITH_CLEANUP(ftruncate_basic); 51272343SngieATF_TC_HEAD(ftruncate_basic, tc) 52272343Sngie{ 53272343Sngie atf_tc_set_md_var(tc, "descr", "A basic test of ftruncate(2)"); 54272343Sngie} 55272343Sngie 56272343SngieATF_TC_BODY(ftruncate_basic, tc) 57272343Sngie{ 58272343Sngie struct stat st; 59272343Sngie size_t i; 60272343Sngie int fd; 61272343Sngie 62272343Sngie fd = open(path, O_RDWR | O_CREAT, 0600); 63272343Sngie ATF_REQUIRE(fd >= 0); 64272343Sngie 65272343Sngie for (i = 0; i < __arraycount(sizes); i++) { 66272343Sngie 67272343Sngie (void)memset(&st, 0, sizeof(struct stat)); 68272343Sngie 69272343Sngie ATF_REQUIRE(ftruncate(fd, sizes[i]) == 0); 70272343Sngie ATF_REQUIRE(fstat(fd, &st) == 0); 71272343Sngie 72272343Sngie (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]); 73272343Sngie 74272343Sngie if (sizes[i] != (size_t)st.st_size) 75272343Sngie atf_tc_fail("ftruncate(2) did not truncate"); 76272343Sngie } 77272343Sngie 78272343Sngie (void)close(fd); 79272343Sngie (void)unlink(path); 80272343Sngie} 81272343Sngie 82272343SngieATF_TC_CLEANUP(ftruncate_basic, tc) 83272343Sngie{ 84272343Sngie (void)unlink(path); 85272343Sngie} 86272343Sngie 87272343SngieATF_TC(ftruncate_err); 88272343SngieATF_TC_HEAD(ftruncate_err, tc) 89272343Sngie{ 90272343Sngie atf_tc_set_md_var(tc, "descr", "Test errors from ftruncate(2)"); 91272343Sngie atf_tc_set_md_var(tc, "require.user", "unprivileged"); 92272343Sngie} 93272343Sngie 94272343SngieATF_TC_BODY(ftruncate_err, tc) 95272343Sngie{ 96272343Sngie int fd; 97272343Sngie 98272343Sngie fd = open("/etc/passwd", O_RDONLY, 0400); 99272343Sngie ATF_REQUIRE(fd >= 0); 100272343Sngie 101272343Sngie errno = 0; 102272343Sngie ATF_REQUIRE_ERRNO(EBADF, ftruncate(-1, 999) == -1); 103272343Sngie 104272343Sngie errno = 0; 105272343Sngie ATF_REQUIRE_ERRNO(EINVAL, ftruncate(fd, 999) == -1); 106272343Sngie 107272343Sngie (void)close(fd); 108272343Sngie} 109272343Sngie 110272343SngieATF_TC_WITH_CLEANUP(truncate_basic); 111272343SngieATF_TC_HEAD(truncate_basic, tc) 112272343Sngie{ 113272343Sngie atf_tc_set_md_var(tc, "descr", "A basic test of truncate(2)"); 114272343Sngie} 115272343Sngie 116272343SngieATF_TC_BODY(truncate_basic, tc) 117272343Sngie{ 118272343Sngie struct stat st; 119272343Sngie size_t i; 120272343Sngie int fd; 121272343Sngie 122272343Sngie fd = open(path, O_RDWR | O_CREAT, 0600); 123272343Sngie ATF_REQUIRE(fd >= 0); 124272343Sngie 125272343Sngie for (i = 0; i < __arraycount(sizes); i++) { 126272343Sngie 127272343Sngie (void)memset(&st, 0, sizeof(struct stat)); 128272343Sngie 129272343Sngie ATF_REQUIRE(truncate(path, sizes[i]) == 0); 130272343Sngie ATF_REQUIRE(fstat(fd, &st) == 0); 131272343Sngie 132272343Sngie (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]); 133272343Sngie 134272343Sngie if (sizes[i] != (size_t)st.st_size) 135272343Sngie atf_tc_fail("truncate(2) did not truncate"); 136272343Sngie } 137272343Sngie 138272343Sngie (void)close(fd); 139272343Sngie (void)unlink(path); 140272343Sngie} 141272343Sngie 142272343SngieATF_TC_CLEANUP(truncate_basic, tc) 143272343Sngie{ 144272343Sngie (void)unlink(path); 145272343Sngie} 146272343Sngie 147272343SngieATF_TC(truncate_err); 148272343SngieATF_TC_HEAD(truncate_err, tc) 149272343Sngie{ 150272343Sngie atf_tc_set_md_var(tc, "descr", "Test errors from truncate(2)"); 151272343Sngie atf_tc_set_md_var(tc, "require.user", "unprivileged"); 152272343Sngie} 153272343Sngie 154272343SngieATF_TC_BODY(truncate_err, tc) 155272343Sngie{ 156273533Sngie#ifndef __NetBSD__ 157273533Sngie char buf[PATH_MAX]; 158273533Sngie#endif 159272343Sngie 160272343Sngie errno = 0; 161272343Sngie ATF_REQUIRE_ERRNO(EFAULT, truncate((void *)-1, 999) == -1); 162272343Sngie 163272343Sngie errno = 0; 164272343Sngie ATF_REQUIRE_ERRNO(EISDIR, truncate("/etc", 999) == -1); 165272343Sngie 166272343Sngie errno = 0; 167272343Sngie ATF_REQUIRE_ERRNO(ENOENT, truncate("/a/b/c/d/e/f/g", 999) == -1); 168272343Sngie 169272343Sngie errno = 0; 170273533Sngie#ifdef __NetBSD__ 171272343Sngie ATF_REQUIRE_ERRNO(EACCES, truncate("/usr/bin/fpr", 999) == -1); 172273533Sngie#else 173273533Sngie snprintf(buf, sizeof(buf), "%s/truncate_test.root_owned", 174273533Sngie atf_tc_get_config_var(tc, "srcdir")); 175273533Sngie ATF_REQUIRE_ERRNO(EACCES, truncate(buf, 999) == -1); 176273533Sngie#endif 177272343Sngie} 178272343Sngie 179272343SngieATF_TP_ADD_TCS(tp) 180272343Sngie{ 181272343Sngie 182272343Sngie ATF_TP_ADD_TC(tp, ftruncate_basic); 183272343Sngie ATF_TP_ADD_TC(tp, ftruncate_err); 184272343Sngie ATF_TP_ADD_TC(tp, truncate_basic); 185272343Sngie ATF_TP_ADD_TC(tp, truncate_err); 186272343Sngie 187272343Sngie return atf_no_error(); 188272343Sngie} 189