Hi, I would like to submit a patch for importing truncate(1) from FreeBSD.
You can find the original source here: https://github.com/freebsd/freebsd-src/tree/main/usr.bin/truncate Please let me know what you think of it and if I should, perhaps, change something. Naveen Index: usr.bin/truncate/Makefile =================================================================== RCS file: usr.bin/truncate/Makefile diff -N usr.bin/truncate/Makefile *** /dev/null 1 Jan 1970 00:00:00 -0000 --- usr.bin/truncate/Makefile 11 Sep 2021 10:22:51 -0000 *************** *** 0 **** --- 1,8 ---- + # $NetBSD$ + + PROG= truncate + + DPADD+= ${LIBUTIL} + LDADD+= -lutil + + .include <bsd.prog.mk> Index: usr.bin/truncate/truncate.1 =================================================================== RCS file: usr.bin/truncate/truncate.1 diff -N usr.bin/truncate/truncate.1 *** /dev/null 1 Jan 1970 00:00:00 -0000 --- usr.bin/truncate/truncate.1 11 Sep 2021 10:22:51 -0000 *************** *** 0 **** --- 1,249 ---- + .\" $NetBSD$ + .\" + .\" Copyright (c) 2000 Sheldon Hearn <sheld...@freebsd.org>. + .\" All rights reserved. + .\" Copyright (c) 2021 The FreeBSD Foundation + .\" + .\" Portions of this manual page were written by Ka Ho Ng <k...@freebsd.org> + .\" under sponsorship from the FreeBSD Foundation. + .\" + .\" Redistribution and use in source and binary forms, with or without + .\" modification, are permitted provided that the following conditions + .\" are met: + .\" 1. Redistributions of source code must retain the above copyright + .\" notice, this list of conditions and the following disclaimer. + .\" 2. Redistributions in binary form must reproduce the above copyright + .\" notice, this list of conditions and the following disclaimer in the + .\" documentation and/or other materials provided with the distribution. + .\" + .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + .\" SUCH DAMAGE. + .\" + .\" $FreeBSD$ + .\" + .Dd August 19, 2021 + .Dt TRUNCATE 1 + .Os + .Sh NAME + .Nm truncate + .Nd truncate, extend the length of files, or perform space management in files + .Sh SYNOPSIS + .Nm + .Op Fl c + .Bk -words + .Fl s Xo + .Sm off + .Op Cm + | - | % | / + .Ar size + .Op Cm SUFFIX + .Sm on + .Xc + .Ek + .Ar + .Nm + .Op Fl c + .Bk -words + .Fl r Ar rfile + .Ek + .Ar + .Nm + .Op Fl c + .Bk -words + .Fl d + .Oo + .Fl o Xo + .Sm off + .Ar offset + .Op Cm SUFFIX + .Sm on + .Xc + .Oc + .Fl l Xo + .Sm off + .Ar length + .Op Cm SUFFIX + .Sm on + .Xc + .Ek + .Ar + .Sh DESCRIPTION + The + .Nm + utility adjusts the length of each regular file given on the command-line, or + performs space management with the given offset and the length over a regular + file given on the command-line. + .Pp + The following options are available: + .Bl -tag -width indent + .It Fl c + Do not create files if they do not exist. + The + .Nm + utility does not treat this as an error. + No error messages are displayed + and the exit value is not affected. + .It Fl r Ar rfile + Truncate or extend files to the length of the file + .Ar rfile . + .It Fl s Xo + .Sm off + .Op Cm + | - | % | / + .Ar size + .Op Cm SUFFIX + .Sm on + .Xc + If the + .Ar size + argument is preceded by a plus sign + .Pq Cm + , + files will be extended by this number of bytes. + If the + .Ar size + argument is preceded by a dash + .Pq Cm - , + file lengths will be reduced by no more than this number of bytes, + to a minimum length of zero bytes. + If the + .Ar size + argument is preceded by a percent sign + .Pq Cm % , + files will be round up to a multiple of this number of bytes. + If the + .Ar size + argument is preceded by a slash sign + .Pq Cm / , + files will be round down to a multiple of this number of bytes, + to a minimum length of zero bytes. + Otherwise, the + .Ar size + argument specifies an absolute length to which all files + should be extended or reduced as appropriate. + .It Fl d + Zero a region in the specified file. + If the underlying file system of the given file supports hole-punching, + file system space deallocation may be performed in the operation region. + .It Fl o Ar offset + The space management operation is performed at the given + .Ar offset + bytes in the file. + If this option is not specified, the operation is performed at the beginning of the file. + .It Fl l Ar length + The length of the operation range in bytes. + This option must always be specified if option + .Fl d + is specified, and must be greater than 0. + .El + .Pp + The + .Ar size , + .Ar offset + and + .Ar length + arguments may be suffixed with one of + .Cm K , + .Cm M , + .Cm G + or + .Cm T + (either upper or lower case) to indicate a multiple of + Kilobytes, Megabytes, Gigabytes or Terabytes + respectively. + .Pp + Exactly one of the + .Fl r , + .Fl s + and + .Fl d + options must be specified. + .Pp + If a file is made smaller, its extra data is lost. + If a file is made larger, + it will be extended as if by writing bytes with the value zero. + If the file does not exist, + it is created unless the + .Fl c + option is specified. + .Pp + Note that, + while truncating a file causes space on disk to be freed, + extending a file does not cause space to be allocated. + To extend a file and actually allocate the space, + it is necessary to explicitly write data to it, + using (for example) the shell's + .Ql >> + redirection syntax, or + .Xr dd 1 . + .Sh EXIT STATUS + .Ex -std + If the operation fails for an argument, + .Nm + will issue a diagnostic + and continue processing the remaining arguments. + .Sh EXAMPLES + Adjust the size of the file + .Pa test_file + to 10 Megabytes but do not create it if it does not exist: + .Bd -literal -offset indent + truncate -c -s +10M test_file + .Ed + .Pp + Same as above but create the file if it does not exist: + .Bd -literal -offset indent + truncate -s +10M test_file + ls -l test_file + -rw-r--r-- 1 root wheel 10485760 Jul 22 18:48 test_file + .Ed + .Pp + Adjust the size of + .Pa test_file + to the size of the kernel and create another file + .Pa test_file2 + with the same size: + .Bd -literal -offset indent + truncate -r /boot/kernel/kernel test_file test_file2 + ls -l /boot/kernel/kernel test_file* + -r-xr-xr-x 1 root wheel 31352552 May 15 14:18 /boot/kernel/kernel* + -rw-r--r-- 1 root wheel 31352552 Jul 22 19:15 test_file + -rw-r--r-- 1 root wheel 31352552 Jul 22 19:15 test_file2 + .Ed + .Pp + Downsize + .Pa test_file + in 5 Megabytes: + .Bd -literal -offset indent + # truncate -s -5M test_file + ls -l test_file* + -rw-r--r-- 1 root wheel 26109672 Jul 22 19:17 test_file + -rw-r--r-- 1 root wheel 31352552 Jul 22 19:15 test_file2 + .Ed + .Sh SEE ALSO + .Xr dd 1 , + .Xr touch 1 , + .Xr fspacectl 2 , + .Xr truncate 2 + .Sh STANDARDS + The + .Nm + utility conforms to no known standards. + .Sh HISTORY + The + .Nm + utility first appeared in + .Fx 4.2 . + .Sh AUTHORS + The + .Nm + utility was written by + .An Sheldon Hearn Aq Mt sheld...@starjuice.net . + Hole-punching support of this + utility was developed by + .An Ka Ho Ng Aq Mt k...@freebsd.org . Index: usr.bin/truncate/truncate.c =================================================================== RCS file: usr.bin/truncate/truncate.c diff -N usr.bin/truncate/truncate.c *** /dev/null 1 Jan 1970 00:00:00 -0000 --- usr.bin/truncate/truncate.c 11 Sep 2021 10:22:51 -0000 *************** *** 0 **** --- 1,222 ---- + /* $NetBSD$ */ + /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2000 Sheldon Hearn <sheld...@freebsd.org>. + * All rights reserved. + * + * Copyright (c) 2021 The FreeBSD Foundation + * + * Portions of this software were developed by Ka Ho Ng <k...@freebsd.org> + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + + #include <sys/stat.h> + + #include <ctype.h> + #include <err.h> + #include <errno.h> + #include <fcntl.h> + #include <stdio.h> + #include <stdlib.h> + #include <unistd.h> + #include <util.h> + + __dead static void usage(void); + + int + main(int argc, char **argv) + { + struct stat sb; + mode_t omode; + off_t oflow, rsize, sz, tsize, round, off, len; + int64_t usz; + int ch, error, fd, oflags, r; + int do_dealloc; + int do_truncate; + int no_create; + int do_relative; + int do_round; + int do_refer; + int got_size; + char *fname, *rname; + + fd = -1; + rsize = tsize = sz = off = 0; + len = -1; + do_dealloc = no_create = do_relative = do_round = do_refer = + got_size = 0; + do_truncate = 1; + error = r = 0; + rname = NULL; + while ((ch = getopt(argc, argv, "cdr:s:o:l:")) != -1) + switch (ch) { + case 'c': + no_create = 1; + break; + case 'd': + do_dealloc = 1; + do_truncate = 0; + break; + case 'r': + do_refer = 1; + rname = optarg; + break; + case 's': + if (*optarg == '+' || *optarg == '-') { + do_relative = 1; + } else if (*optarg == '%' || *optarg == '/') { + do_round = 1; + } + if (dehumanize_number(do_relative || do_round ? + optarg + 1 : optarg, + &usz) == -1 || usz <= 0) + errx(EXIT_FAILURE, + "invalid size argument `%s'", optarg); + + sz = (*optarg == '-' || *optarg == '/') ? + -usz : usz; + got_size = 1; + break; + case 'o': + if (dehumanize_number(optarg, &usz) == -1 || + usz < 0) + errx(EXIT_FAILURE, + "invalid offset argument `%s'", optarg); + + off = usz; + break; + case 'l': + if (dehumanize_number(optarg, &usz) == -1 || + usz <= 0) + errx(EXIT_FAILURE, + "invalid length argument `%s'", optarg); + + len = usz; + break; + default: + usage(); + /* NOTREACHED */ + } + + argv += optind; + argc -= optind; + + /* + * Exactly one of do_refer, got_size or do_dealloc must be specified. + * Since do_relative implies got_size, do_relative, do_refer and + * do_dealloc are also mutually exclusive. If do_dealloc is specified, + * the length argument must be set. See usage() for allowed + * invocations. + */ + if (argc < 1 || do_refer + got_size + do_dealloc != 1 || + (do_dealloc == 1 && len == -1)) + usage(); + if (do_refer == 1) { + if (stat(rname, &sb) == -1) + err(EXIT_FAILURE, "%s", rname); + tsize = sb.st_size; + } else if (do_relative == 1 || do_round == 1) + rsize = sz; + else if (do_dealloc == 0) + tsize = sz; + + if (no_create) + oflags = O_WRONLY; + else + oflags = O_WRONLY | O_CREAT; + omode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; + + while ((fname = *argv++) != NULL) { + if (fd != -1) + close(fd); + if ((fd = open(fname, oflags, omode)) == -1) { + if (errno != ENOENT) { + warn("%s", fname); + error++; + } + continue; + } + if (do_relative == 1) { + if (fstat(fd, &sb) == -1) { + warn("%s", fname); + error++; + continue; + } + oflow = sb.st_size + rsize; + if (oflow < (sb.st_size + rsize)) { + errno = EFBIG; + warn("%s", fname); + error++; + continue; + } + tsize = oflow; + } + if (do_round == 1) { + if (fstat(fd, &sb) == -1) { + warn("%s", fname); + error++; + continue; + } + sz = rsize; + if (sz < 0) + sz = -sz; + if (sb.st_size % sz) { + round = sb.st_size / sz; + if (rsize > 0) + round++; + tsize = round * sz; + } else + tsize = sb.st_size; + } + if (tsize < 0) + tsize = 0; + + if (do_dealloc == 1) { + r = fdiscard(fd, off, len); + } + if (do_truncate == 1) + r = ftruncate(fd, tsize); + if (r == -1) { + warn("%s", fname); + error++; + } + } + if (fd != -1) + close(fd); + + return (error ? EXIT_FAILURE : EXIT_SUCCESS); + } + + static void + usage(void) + { + const char *pnam = getprogname(); + fprintf(stderr, "usage:\t%s %s\n\t%s %s\n\t%s %s\n", + pnam, "[-c] -s [+|-|%|/]size[K|k|M|m|G|g|T|t] file ...", + pnam, "[-c] -r rfile file ...", + pnam, "[-c] -d [-o offset[K|k|M|m|G|g|T|t]] -l length[K|k|M|m|G|g|T|t] file ..."); + exit(EXIT_FAILURE); + } ? tests/usr.bin/truncate/Atffile ? tests/usr.bin/truncate/t_grow ? tests/usr.bin/truncate/t_misc ? tests/usr.bin/truncate/t_shrink Index: usr.bin/Makefile =================================================================== RCS file: /cvsroot/src/usr.bin/Makefile,v retrieving revision 1.235 diff -c -c -r1.235 Makefile *** usr.bin/Makefile 7 May 2021 21:51:20 -0000 1.235 --- usr.bin/Makefile 11 Sep 2021 10:22:53 -0000 *************** *** 29,35 **** spell split stat su sys_info systat \ tabs tail talk tcopy tee telnet tftp tic time timeout tip touch \ tput \ ! tr true tset tsort tty ul uname unexpand unifdef \ uniq units unvis unzip usbhidaction usbhidctl users utoppya \ uudecode uuencode uuidgen vacation vgrind videoctl vis \ vmstat vndcompress w \ --- 29,35 ---- spell split stat su sys_info systat \ tabs tail talk tcopy tee telnet tftp tic time timeout tip touch \ tput \ ! tr true truncate tset tsort tty ul uname unexpand unifdef \ uniq units unvis unzip usbhidaction usbhidctl users utoppya \ uudecode uuencode uuidgen vacation vgrind videoctl vis \ vmstat vndcompress w \ Index: tests/usr.bin/Makefile =================================================================== RCS file: /cvsroot/src/tests/usr.bin/Makefile,v retrieving revision 1.34 diff -c -c -r1.34 Makefile *** tests/usr.bin/Makefile 1 Nov 2020 22:28:32 -0000 1.34 --- tests/usr.bin/Makefile 11 Sep 2021 10:22:53 -0000 *************** *** 9,15 **** diff dirname find fstat gdb grep gzip id indent \ infocmp jot ld locale m4 make mixerctl mkdep nbperf \ netpgpverify patch pkill pr printf pwhash rump_server \ ! shmif_dumpbus sdiff sed sort tar tmux tr unifdef uniq \ vmstat xlint ztest .if ${MKCXX} != "no" --- 9,15 ---- diff dirname find fstat gdb grep gzip id indent \ infocmp jot ld locale m4 make mixerctl mkdep nbperf \ netpgpverify patch pkill pr printf pwhash rump_server \ ! shmif_dumpbus sdiff sed sort tar tmux tr truncate unifdef uniq \ vmstat xlint ztest .if ${MKCXX} != "no" Index: etc/mtree/NetBSD.dist.tests =================================================================== RCS file: /cvsroot/src/etc/mtree/NetBSD.dist.tests,v retrieving revision 1.187 diff -c -c -r1.187 NetBSD.dist.tests *** etc/mtree/NetBSD.dist.tests 12 Aug 2021 11:50:42 -0000 1.187 --- etc/mtree/NetBSD.dist.tests 11 Sep 2021 10:22:54 -0000 *************** *** 458,463 **** --- 458,464 ---- ./usr/tests/usr.bin/tar ./usr/tests/usr.bin/tmux ./usr/tests/usr.bin/tr + ./usr/tests/usr.bin/truncate ./usr/tests/usr.bin/unifdef ./usr/tests/usr.bin/uniq ./usr/tests/usr.bin/vmstat Index: distrib/sets/lists/tests/mi =================================================================== RCS file: /cvsroot/src/distrib/sets/lists/tests/mi,v retrieving revision 1.1111 diff -c -c -r1.1111 mi *** distrib/sets/lists/tests/mi 12 Aug 2021 15:06:39 -0000 1.1111 --- distrib/sets/lists/tests/mi 11 Sep 2021 10:22:56 -0000 *************** *** 6095,6100 **** --- 6095,6105 ---- ./usr/tests/usr.bin/tr/Atffile tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/tr/Kyuafile tests-usr.bin-tests compattestfile,atf,kyua ./usr/tests/usr.bin/tr/t_basic tests-usr.bin-tests compattestfile,atf + ./usr/tests/usr.bin/truncate/ tests-usr.bin-tests compattestfile,atf + ./usr/tests/usr.bin/truncate/Atffile tests-usr.bin-tests compattestfile,atf + ./usr/tests/usr.bin/truncate/t_grow tests-usr.bin-tests compattestfile,atf + ./usr/tests/usr.bin/truncate/t_misc tests-usr.bin-tests compattestfile,atf + ./usr/tests/usr.bin/truncate/t_shrink tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/unifdef tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/unifdef/Atffile tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/unifdef/Kyuafile tests-usr.bin-tests compattestfile,atf,kyua Index: tests/usr.bin/truncate/Makefile =================================================================== RCS file: tests/usr.bin/truncate/Makefile diff -N tests/usr.bin/truncate/Makefile *** /dev/null 1 Jan 1970 00:00:00 -0000 --- tests/usr.bin/truncate/Makefile 11 Sep 2021 10:22:56 -0000 *************** *** 0 **** --- 1,11 ---- + # $NetBSD$ + + .include <bsd.own.mk> + + TESTSDIR= ${TESTSBASE}/usr.bin/truncate + + TESTS_SH+= t_grow + TESTS_SH+= t_shrink + TESTS_SH+= t_misc + + .include <bsd.test.mk> Index: tests/usr.bin/truncate/t_grow.sh =================================================================== RCS file: tests/usr.bin/truncate/t_grow.sh diff -N tests/usr.bin/truncate/t_grow.sh *** /dev/null 1 Jan 1970 00:00:00 -0000 --- tests/usr.bin/truncate/t_grow.sh 11 Sep 2021 10:22:56 -0000 *************** *** 0 **** --- 1,122 ---- + # $NetBSD$ + # Copyright (c) 2021 The NetBSD Foundation, Inc. + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # 1. Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # 2. Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in the + # documentation and/or other materials provided with the distribution. + # + # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + # POSSIBILITY OF SUCH DAMAGE. + # + + server="rump_server -lrumpvfs -lrumpdev_disk -lrumpfs_ffs -d key=/dev/dk,hostpath=ffs.img,size=host" + + export RUMP_SERVER=unix://ffs + + exmount='rumpfs on / type rumpfs (local) + /dev/dk on /mnt type ffs (local) + ' + + t_init() + { + atf_check -s exit:0 -o ignore -e ignore newfs -b 32k -f 4k -F -s 10M ffs.img + + atf_check -s exit:0 -o ignore -e ignore ${server} ${RUMP_SERVER} + + export LD_PRELOAD=/usr/lib/librumphijack.so + atf_check -s exit:0 -o ignore -e ignore mkdir /rump/mnt + export RUMPHIJACK=vfs=all,blanket=/dev/dk:/mnt + atf_check -s exit:0 -o ignore -e ignore mount /dev/dk /mnt + atf_check -s exit:0 -o inline:"${exmount}" mount + } + + t_cleanup() + { + rump.halt + } + + atf_test_case abs_grow + abs_grow_head() + { + atf_set "descr" "Tests that truncate can grow a file to absolute length" + atf_set "use.fs" "true" + atf_set "require.progs" "ls awk du" + } + abs_grow_body() + { + t_init + + # truncate should allocate the first and the last block only + atf_check -s exit:0 -o ignore -e ignore truncate -s 10M /mnt/test_file + atf_check_equal $(du -s /mnt/test_file | awk '{print $1}') 128 + atf_check_equal $(ls -l /mnt/test_file | awk '{print $5}') $((10 * 1024 * 1024)) + + # truncate should allocate 3 blocks in this case since it extends the file + atf_check -s exit:0 -o ignore -e ignore truncate -s 20M /mnt/test_file + atf_check_equal $(du /mnt/test_file | awk '{print $1}') 192 + atf_check_equal $(ls -l /mnt/test_file | awk '{print $5}') $((20 * 1024 * 1024)) + + t_cleanup + } + + atf_test_case rela_grow + rela_grow_head() + { + atf_set "descr" "Check truncate can grow file to relative length" + atf_set "use.fs" "true" + atf_set "require.progs" "ls awk du" + } + rela_grow_body() + { + t_init + + # truncate should allocate the first and the last block only + atf_check -s exit:0 -o ignore -e ignore truncate -s 10M /mnt/test_file + atf_check_equal $(du -s /mnt/test_file | awk '{print $1}') 128 + atf_check_equal $(ls -l /mnt/test_file | awk '{print $5}') $((10 * 1024 * 1024)) + + # truncate should allocate 3 blocks in this case since it extends the file + atf_check -s exit:0 -o ignore -e ignore truncate -s +10M /mnt/test_file + atf_check_equal $(du /mnt/test_file | awk '{print $1}') 192 + atf_check_equal $(ls -l /mnt/test_file | awk '{print $5}') $((20 * 1024 * 1024)) + + t_cleanup + } + + atf_test_case nocreate + nocreate_head() + { + atf_set "descr" "Check file is not created with -c" + atf_set "use.fs" "true" + } + nocreate_body() + { + t_init + + # test_file should not exist + atf_check -s exit:0 -o ignore -e ignore truncate -c -s 10M /mnt/test_file + atf_check -s not-exit:0 -e ignore 'ls /mnt/test_file' + + t_cleanup + } + + atf_init_test_cases() { + atf_add_test_case abs_grow + atf_add_test_case rela_grow + atf_add_test_case nocreate + } Index: tests/usr.bin/truncate/t_misc.sh =================================================================== RCS file: tests/usr.bin/truncate/t_misc.sh diff -N tests/usr.bin/truncate/t_misc.sh *** /dev/null 1 Jan 1970 00:00:00 -0000 --- tests/usr.bin/truncate/t_misc.sh 11 Sep 2021 10:22:56 -0000 *************** *** 0 **** --- 1,153 ---- + # $NetBSD$ + # Copyright (c) 2021 The NetBSD Foundation, Inc. + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # 1. Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # 2. Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in the + # documentation and/or other materials provided with the distribution. + # + # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + # POSSIBILITY OF SUCH DAMAGE. + # + + server="rump_server -lrumpvfs -lrumpdev_disk -lrumpfs_ffs -d key=/dev/dk,hostpath=ffs.img,size=host" + + export RUMP_SERVER=unix://ffs + + exmount='rumpfs on / type rumpfs (local) + /dev/dk on /mnt type ffs (local) + ' + + t_init() + { + atf_check -s exit:0 -o ignore -e ignore newfs -b 32k -f 4k -F -s 10M ffs.img + atf_check -s exit:0 -o ignore -e ignore ${server} ${RUMP_SERVER} + + export LD_PRELOAD=/usr/lib/librumphijack.so + atf_check -s exit:0 -o ignore -e ignore mkdir /rump/mnt + export RUMPHIJACK=vfs=all,blanket=/dev/dk:/mnt + atf_check -s exit:0 -o ignore -e ignore mount /dev/dk /mnt + atf_check -s exit:0 -o inline:"${exmount}" mount + } + + t_cleanup() + { + rump.halt + } + + atf_test_case reference + reference_head() + { + atf_set "descr" "Tests that truncate can use a reference file" + atf_set "use.fs" "true" + atf_set "require.progs" "ls awk du" + } + reference_body() + { + t_init + + # create a reference file + atf_check -s exit:0 -o ignore -e ignore truncate -s 10M /mnt/test_file1 + atf_check_equal $(du -s /mnt/test_file1 | awk '{print $1}') 128 + atf_check_equal $(ls -l /mnt/test_file1 | awk '{print $5}') $((10 * 1024 * 1024)) + + # truncate should extend the file to the length of the reference file + atf_check -s exit:0 -o ignore -e ignore truncate -r /mnt/test_file1 /mnt/test_file2 + atf_check_equal $(du -s /mnt/test_file2 | awk '{print $1}') 128 + atf_check_equal $(ls -l /mnt/test_file2 | awk '{print $5}') $((10 * 1024 * 1024)) + + t_cleanup + } + + atf_test_case negative + negative_head() + { + atf_set "descr" "Tests that truncate treats negative size as zero" + atf_set "use.fs" "true" + atf_set "require.progs" "ls awk du" + } + negative_body() + { + t_init + + # create/extend a file + atf_check -s exit:0 -o ignore -e ignore truncate -s 10M /mnt/test_file + atf_check_equal $(du -s /mnt/test_file | awk '{print $1}') 128 + atf_check_equal $(ls -l /mnt/test_file | awk '{print $5}') $((10 * 1024 * 1024)) + + # truncate should shrink the file to zero size + atf_check -s exit:0 -o ignore -e ignore truncate -s -100M /mnt/test_file + atf_check_equal $(du -s /mnt/test_file | awk '{print $1}') 0 + atf_check_equal $(ls -l /mnt/test_file | awk '{print $5}') 0 + + t_cleanup + } + + atf_test_case roundup + roundup_head() + { + atf_set "descr" "Tests that truncate rounds up the size of the file" + atf_set "use.fs" "true" + atf_set "require.progs" "ls awk du" + } + roundup_body() + { + t_init + + # create/extend a file + atf_check -s exit:0 -o ignore -e ignore truncate -s 6M /mnt/test_file + atf_check_equal $(du -s /mnt/test_file | awk '{print $1}') 128 + atf_check_equal $(ls -l /mnt/test_file | awk '{print $5}') $((6 * 1024 * 1024)) + + # truncate should round up the size of the file + atf_check -s exit:0 -o ignore -e ignore truncate -s %5M /mnt/test_file + atf_check_equal $(du -s /mnt/test_file | awk '{print $1}') 192 + atf_check_equal $(ls -l /mnt/test_file | awk '{print $5}') $((10 * 1024 * 1024)) + + t_cleanup + } + + atf_test_case rounddown + rounddown_head() + { + atf_set "descr" "Tests that truncate rounds down the size of the file" + atf_set "use.fs" "true" + atf_set "require.progs" "ls awk du" + } + rounddown_body() + { + t_init + + # create/extend a file + atf_check -s exit:0 -o ignore -e ignore truncate -s 9M /mnt/test_file + atf_check_equal $(du -s /mnt/test_file | awk '{print $1}') 128 + atf_check_equal $(ls -l /mnt/test_file | awk '{print $5}') $((9 * 1024 * 1024)) + + # truncate should round down the size of the file + atf_check -s exit:0 -o ignore -e ignore truncate -s /2M /mnt/test_file + atf_check_equal $(du -s /mnt/test_file | awk '{print $1}') 64 + atf_check_equal $(ls -l /mnt/test_file | awk '{print $5}') $((8 * 1024 * 1024)) + + t_cleanup + } + + atf_init_test_cases() { + atf_add_test_case reference + atf_add_test_case rounddown + atf_add_test_case roundup + atf_add_test_case negative + } Index: tests/usr.bin/truncate/t_shrink.sh =================================================================== RCS file: tests/usr.bin/truncate/t_shrink.sh diff -N tests/usr.bin/truncate/t_shrink.sh *** /dev/null 1 Jan 1970 00:00:00 -0000 --- tests/usr.bin/truncate/t_shrink.sh 11 Sep 2021 10:22:56 -0000 *************** *** 0 **** --- 1,103 ---- + # $NetBSD$ + # Copyright (c) 2021 The NetBSD Foundation, Inc. + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # 1. Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # 2. Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in the + # documentation and/or other materials provided with the distribution. + # + # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + # POSSIBILITY OF SUCH DAMAGE. + # + + server="rump_server -lrumpvfs -lrumpdev_disk -lrumpfs_ffs -d key=/dev/dk,hostpath=ffs.img,size=host" + + export RUMP_SERVER=unix://ffs + + exmount='rumpfs on / type rumpfs (local) + /dev/dk on /mnt type ffs (local) + ' + + t_init() + { + atf_check -s exit:0 -o ignore -e ignore newfs -b 32k -f 4k -F -s 10M ffs.img + atf_check -s exit:0 -o ignore -e ignore ${server} ${RUMP_SERVER} + + export LD_PRELOAD=/usr/lib/librumphijack.so + atf_check -s exit:0 -o ignore -e ignore mkdir /rump/mnt + export RUMPHIJACK=vfs=all,blanket=/dev/dk:/mnt + atf_check -s exit:0 -o ignore -e ignore mount /dev/dk /mnt + atf_check -s exit:0 -o inline:"${exmount}" mount + } + + t_cleanup() + { + rump.halt + } + + atf_test_case abs_shrink + abs_shrink_head() + { + atf_set "descr" "Tests that truncate can shrink a file to absolute length" + atf_set "use.fs" "true" + atf_set "require.progs" "ls awk du" + } + abs_shrink_body() + { + t_init + + # truncate should allocate the first and the last block only + atf_check -s exit:0 -o ignore -e ignore truncate -s 10M /mnt/test_file + atf_check_equal $(du -s /mnt/test_file | awk '{print $1}') 128 + atf_check_equal $(ls -l /mnt/test_file | awk '{print $5}') $((10 * 1024 * 1024)) + + # truncate should allocate only one block post shrink + atf_check -s exit:0 -o ignore -e ignore truncate -s 5M /mnt/test_file + atf_check_equal $(du -s /mnt/test_file | awk '{print $1}') 64 + atf_check_equal $(ls -l /mnt/test_file | awk '{print $5}') $((5 * 1024 * 1024)) + + t_cleanup + } + + atf_test_case rela_shrink + rela_shrink_head() + { + atf_set "descr" "Tests that truncate can shrink a file to relative length" + atf_set "use.fs" "true" + atf_set "require.progs" "ls awk du" + } + rela_shrink_body() + { + t_init + + # truncate should allocate the first and the last block only + atf_check -s exit:0 -o ignore -e ignore truncate -s 10M /mnt/test_file + atf_check_equal $(du -s /mnt/test_file | awk '{print $1}') 128 + atf_check_equal $(ls -l /mnt/test_file | awk '{print $5}') $((10 * 1024 * 1024)) + + # truncate should allocate only one block post shrink + atf_check -s exit:0 -o ignore -e ignore truncate -s -5M /mnt/test_file + atf_check_equal $(du -s /mnt/test_file | awk '{print $1}') 64 + atf_check_equal $(ls -l /mnt/test_file | awk '{print $5}') $((5 * 1024 * 1024)) + + t_cleanup + } + + atf_init_test_cases() { + atf_add_test_case abs_shrink + atf_add_test_case rela_shrink + } ----- End forwarded message ----- Naveen