Index: stable/10/etc/mtree/BSD.tests.dist =================================================================== --- stable/10/etc/mtree/BSD.tests.dist (revision 275584) +++ stable/10/etc/mtree/BSD.tests.dist (revision 275585) @@ -1,318 +1,320 @@ # $FreeBSD$ # # Please see the file src/etc/mtree/README before making changes to this file. # /set type=dir uname=root gname=wheel mode=0755 . include atf-c .. atf-c++ .. .. share atf .. doc atf .. pjdfstest .. .. .. tests bin date .. mv .. pax .. pkill .. sh builtins .. errors .. execution .. expansion .. parameters .. parser .. set-e .. .. test .. .. cddl lib .. sbin .. usr.bin .. usr.sbin .. .. etc .. games .. gnu lib .. usr.bin .. .. lib atf libatf-c detail .. .. libatf-c++ detail .. .. test-programs .. .. libcrypt .. libmp .. libutil .. .. libexec atf atf-check .. atf-sh .. .. .. sbin dhclient .. devd .. growfs .. mdconfig .. .. secure lib .. libexec .. usr.bin .. usr.sbin .. .. share examples tests atf .. plain .. .. .. .. sys kern .. netinet .. pjdfstest chflags .. chmod .. chown .. ftruncate .. granular .. link .. mkdir .. mkfifo .. mknod .. open .. rename .. rmdir .. symlink .. truncate .. unlink .. .. .. usr.bin apply .. calendar .. comm .. file2c .. join .. jot .. lastcomm .. m4 .. make archives fmt_44bsd .. fmt_44bsd_mod .. fmt_oldbsd .. .. basic t0 .. t1 .. t2 .. t3 .. .. execution ellipsis .. empty .. joberr .. plus .. .. shell builtin .. meta .. path .. path_select .. replace .. select .. .. suffixes basic .. src_wild1 .. src_wild2 .. .. syntax directive-t0 .. enl .. funny-targets .. semi .. .. sysmk t0 2 1 .. .. mk .. .. t1 2 1 .. .. mk .. .. t2 2 1 .. .. mk .. .. .. variables modifier_M .. modifier_t .. opt_V .. t0 .. .. .. ncal .. printf .. sed regress.multitest.out .. .. tr .. + truncate + .. uudecode .. uuencode .. xargs .. yacc yacc .. .. .. usr.sbin etcupdate .. newsyslog .. pw .. sa .. .. .. .. # vim: set expandtab ts=4 sw=4: Index: stable/10/usr.bin/truncate/Makefile =================================================================== --- stable/10/usr.bin/truncate/Makefile (revision 275584) +++ stable/10/usr.bin/truncate/Makefile (revision 275585) @@ -1,7 +1,13 @@ # $FreeBSD$ +.include + PROG= truncate DPADD= ${LIBUTIL} LDADD= -lutil + +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif .include Index: stable/10/usr.bin/truncate/tests/Makefile =================================================================== --- stable/10/usr.bin/truncate/tests/Makefile (nonexistent) +++ stable/10/usr.bin/truncate/tests/Makefile (revision 275585) @@ -0,0 +1,6 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/usr.bin/truncate +ATF_TESTS_SH= truncate_test + +.include Property changes on: stable/10/usr.bin/truncate/tests/Makefile ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: stable/10/usr.bin/truncate/tests/truncate_test.sh =================================================================== --- stable/10/usr.bin/truncate/tests/truncate_test.sh (nonexistent) +++ stable/10/usr.bin/truncate/tests/truncate_test.sh (revision 275585) @@ -0,0 +1,402 @@ +# +# Copyright 2014, Google 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: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT +# OWNER 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$ +# + +# Helper function that is always used to create and fill stderr.txt for these +# tests. +_custom_create_file() +{ + # The first argument is a command. + # The second is just a string. + case "${1}" in + creat) > stderr.txt ;; + print) [ "${2}" ] && \ + printf "%s\n" "${2}" >> stderr.txt ;; + esac +} + +# Helper function that create the file stderr.txt that contains the string +# passed in as the first argument. +create_stderr_file() +{ + _custom_create_file creat + _custom_create_file print "${1}" +} + +# Helper function that create the file stderr.txt that contains the expected +# truncate utility usage message. +create_stderr_usage_file() +{ + _custom_create_file creat + _custom_create_file print "${1}" + _custom_create_file print \ + "usage: truncate [-c] -s [+|-]size[K|k|M|m|G|g|T|t] file ..." + _custom_create_file print " truncate [-c] -r rfile file ..." +} + +atf_test_case illegal_option +illegal_option_head() +{ + atf_set "descr" "Verifies that truncate exits >0 when passed an" \ + "invalid command line option" +} +illegal_option_body() +{ + create_stderr_usage_file 'truncate: illegal option -- 7' + + # We expect the error message, with no new files. + atf_check -s not-exit:0 -e file:stderr.txt truncate -7 -s0 output.txt + [ ! -e output.txt ] || atf_fail "output.txt should not exist" +} + +atf_test_case illegal_size +illegal_size_head() +{ + atf_set "descr" "Verifies that truncate exits >0 when passed an" \ + "invalid power of two convention" +} +illegal_size_body() +{ + create_stderr_file "truncate: invalid size argument \`+1L'" + + # We expect the error message, with no new files. + atf_check -s not-exit:0 -e file:stderr.txt truncate -s+1L output.txt + [ ! -e output.txt ] || atf_fail "output.txt should not exist" +} + +atf_test_case too_large_size +too_large_size_head() +{ + atf_set "descr" "Verifies that truncate exits >0 when passed an" \ + "a size that is INT64_MAX < size <= UINT64_MAX" +} +too_large_size_body() +{ + create_stderr_file "truncate: invalid size argument \`8388608t'" + + # We expect the error message, with no new files. + atf_check -s not-exit:0 -e file:stderr.txt \ + truncate -s8388608t output.txt + [ ! -e output.txt ] || atf_fail "output.txt should not exist" +} + +atf_test_case opt_c +opt_c_head() +{ + atf_set "descr" "Verifies that -c prevents creation of new files" +} +opt_c_body() +{ + # No new files and truncate returns 0 as if this is a success. + atf_check truncate -c -s 0 doesnotexist.txt + [ ! -e output.txt ] || atf_fail "doesnotexist.txt should not exist" + > reference + atf_check truncate -c -r reference doesnotexist.txt + [ ! -e output.txt ] || atf_fail "doesnotexist.txt should not exist" + + create_stderr_file + + # The existing file will be altered by truncate. + > exists.txt + atf_check -e file:stderr.txt truncate -c -s1 exists.txt + [ -s exists.txt ] || atf_fail "exists.txt be larger than zero bytes" +} + +atf_test_case opt_rs +opt_rs_head() +{ + atf_set "descr" "Verifies that truncate command line flags" \ + "-s and -r cannot be specifed together" +} +opt_rs_body() +{ + create_stderr_usage_file + + # Force an error due to the use of both -s and -r. + > afile + atf_check -s not-exit:0 -e file:stderr.txt truncate -s0 -r afile afile +} + +atf_test_case no_files +no_files_head() +{ + atf_set "descr" "Verifies that truncate needs a list of files on" \ + "the command line" +} +no_files_body() +{ + create_stderr_usage_file + + # A list of files must be present on the command line. + atf_check -s not-exit:0 -e file:stderr.txt truncate -s1 +} + +atf_test_case bad_refer +bad_refer_head() +{ + atf_set "descr" "Verifies that truncate detects a non-existent" \ + "reference file" +} +bad_refer_body() +{ + create_stderr_file "truncate: afile: No such file or directory" + + # The reference file must exist before you try to use it. + atf_check -s not-exit:0 -e file:stderr.txt truncate -r afile afile + [ ! -e afile ] || atf_fail "afile should not exist" +} + +atf_test_case bad_truncate cleanup +bad_truncate_head() +{ + atf_set "descr" "Verifies that truncate reports an error during" \ + "truncation" +} +bad_truncate_body() +{ + create_stderr_file "truncate: exists.txt: Operation not permitted" + + # Trying to get the ftruncate() call to return -1. + > exists.txt + atf_check chflags uimmutable exists.txt + + atf_check -s not-exit:0 -e file:stderr.txt truncate -s1 exists.txt +} +bad_truncate_cleanup() +{ + chflags 0 exists.txt +} + +atf_test_case new_absolute_grow +new_absolute_grow_head() +{ + atf_set "descr" "Verifies truncate can make and grow a new 1m file" +} +new_absolute_grow_body() +{ + create_stderr_file + + # Create a new file and grow it to 1024 bytes. + atf_check -s exit:0 -e file:stderr.txt truncate -s1k output.txt + atf_check -s exit:1 cmp -s output.txt /dev/zero + eval $(stat -s output.txt) + [ ${st_size} -eq 1024 ] || atf_fail "expected file size of 1k" + + create_stderr_file + + # Grow the existing file to 1M. We are using absolute sizes. + atf_check -s exit:0 -e file:stderr.txt truncate -c -s1M output.txt + atf_check -s exit:1 cmp -s output.txt /dev/zero + eval $(stat -s output.txt) + [ ${st_size} -eq 1048576 ] || atf_fail "expected file size of 1m" +} + +atf_test_case new_absolute_shrink +new_absolute_shrink_head() +{ + atf_set "descr" "Verifies that truncate can make and" \ + "shrink a new 1m file" +} +new_absolute_shrink_body() +{ + create_stderr_file + + # Create a new file and grow it to 1048576 bytes. + atf_check -s exit:0 -e file:stderr.txt truncate -s1M output.txt + atf_check -s exit:1 cmp -s output.txt /dev/zero + eval $(stat -s output.txt) + [ ${st_size} -eq 1048576 ] || atf_fail "expected file size of 1m" + + create_stderr_file + + # Shrink the existing file to 1k. We are using absolute sizes. + atf_check -s exit:0 -e file:stderr.txt truncate -s1k output.txt + atf_check -s exit:1 cmp -s output.txt /dev/zero + eval $(stat -s output.txt) + [ ${st_size} -eq 1024 ] || atf_fail "expected file size of 1k" +} + +atf_test_case new_relative_grow +new_relative_grow_head() +{ + atf_set "descr" "Verifies truncate can make and grow a new 1m file" \ + "using relative sizes" +} +new_relative_grow_body() +{ + create_stderr_file + + # Create a new file and grow it to 1024 bytes. + atf_check -s exit:0 -e file:stderr.txt truncate -s+1k output.txt + atf_check -s exit:1 cmp -s output.txt /dev/zero + eval $(stat -s output.txt) + [ ${st_size} -eq 1024 ] || atf_fail "expected file size of 1k" + + create_stderr_file + + # Grow the existing file to 1M. We are using relative sizes. + atf_check -s exit:0 -e file:stderr.txt truncate -s+1047552 output.txt + atf_check -s exit:1 cmp -s output.txt /dev/zero + eval $(stat -s output.txt) + [ ${st_size} -eq 1048576 ] || atf_fail "expected file size of 1m" +} + +atf_test_case new_relative_shrink +new_relative_shrink_head() +{ + atf_set "descr" "Verifies truncate can make and shrink a new 1m file" \ + "using relative sizes" +} +new_relative_shrink_body() +{ + create_stderr_file + + # Create a new file and grow it to 1049600 bytes. + atf_check -s exit:0 -e file:stderr.txt truncate -s+1049600 output.txt + atf_check -s exit:1 cmp -s output.txt /dev/zero + eval $(stat -s output.txt) + [ ${st_size} -eq 1049600 ] || atf_fail "expected file size of 1m" + + create_stderr_file + + # Shrink the existing file to 1k. We are using relative sizes. + atf_check -s exit:0 -e file:stderr.txt truncate -s-1M output.txt + atf_check -s exit:1 cmp -s output.txt /dev/zero + eval $(stat -s output.txt) + [ ${st_size} -eq 1024 ] || atf_fail "expected file size of 1k" +} + +atf_test_case cannot_open +cannot_open_head() +{ + atf_set "descr" "Verifies truncate handles open failures correctly" \ + "in a list of files" + atf_set "require.user" "unprivileged" +} +cannot_open_body() +{ + # Create three files -- the middle file cannot allow writes. + > before + > 0000 + > after + atf_check chmod 0000 0000 + + create_stderr_file "truncate: 0000: Permission denied" + + # Create a new file and grow it to 1024 bytes. + atf_check -s not-exit:0 -e file:stderr.txt \ + truncate -c -s1k before 0000 after + eval $(stat -s before) + [ ${st_size} -eq 1024 ] || atf_fail "expected file size of 1k" + eval $(stat -s after) + [ ${st_size} -eq 1024 ] || atf_fail "expected file size of 1k" + eval $(stat -s 0000) + [ ${st_size} -eq 0 ] || atf_fail "expected file size of zero" +} + +atf_test_case reference +reference_head() +{ + atf_set "descr" "Verifies that truncate can use a reference file" +} +reference_body() +{ + # Create a 4 byte reference file. + printf "123\n" > reference + eval $(stat -s reference) + [ ${st_size} -eq 4 ] || atf_fail "reference file should be 4 bytes" + + create_stderr_file + + # Create a new file and grow it to 4 bytes. + atf_check -e file:stderr.txt truncate -r reference afile + eval $(stat -s afile) + [ ${st_size} -eq 4 ] || atf_fail "new file should also be 4 bytes" +} + +atf_test_case new_zero +new_zero_head() +{ + atf_set "descr" "Verifies truncate can make and grow zero byte file" +} +new_zero_body() +{ + create_stderr_file + + # Create a new file and grow it to zero bytes. + atf_check -s exit:0 -e file:stderr.txt truncate -s0 output.txt + eval $(stat -s output.txt) + [ ${st_size} -eq 0 ] || atf_fail "expected file size of zero" + + # Pretend to grow the file. + atf_check -s exit:0 -e file:stderr.txt truncate -s+0 output.txt + eval $(stat -s output.txt) + [ ${st_size} -eq 0 ] || atf_fail "expected file size of zero" +} + +atf_test_case negative +negative_head() +{ + atf_set "descr" "Verifies truncate treats negative sizes as zero" +} +negative_body() +{ + # Create a 5 byte file. + printf "abcd\n" > afile + eval $(stat -s afile) + [ ${st_size} -eq 5 ] || atf_fail "afile file should be 5 bytes" + + create_stderr_file + + # Create a new file and do a 100 byte negative relative shrink. + atf_check -e file:stderr.txt truncate -s-100 afile + eval $(stat -s afile) + [ ${st_size} -eq 0 ] || atf_fail "new file should now be zero bytes" +} + +atf_init_test_cases() +{ + atf_add_test_case illegal_option + atf_add_test_case illegal_size + atf_add_test_case too_large_size + atf_add_test_case opt_c + atf_add_test_case opt_rs + atf_add_test_case no_files + atf_add_test_case bad_refer + atf_add_test_case bad_truncate + atf_add_test_case cannot_open + atf_add_test_case new_absolute_grow + atf_add_test_case new_absolute_shrink + atf_add_test_case new_relative_grow + atf_add_test_case new_relative_shrink + atf_add_test_case reference + atf_add_test_case new_zero + atf_add_test_case negative +} Property changes on: stable/10/usr.bin/truncate/tests/truncate_test.sh ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: stable/10/usr.bin/truncate/truncate.c =================================================================== --- stable/10/usr.bin/truncate/truncate.c (revision 275584) +++ stable/10/usr.bin/truncate/truncate.c (revision 275585) @@ -1,160 +1,162 @@ /*- * Copyright (c) 2000 Sheldon Hearn . * 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 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. * */ #ifndef lint static const char rcsid[] = "$FreeBSD$"; #endif #include #include #include #include #include #include #include #include #include static void usage(void); static int no_create; static int do_relative; static int do_refer; static int got_size; int main(int argc, char **argv) { struct stat sb; mode_t omode; - off_t oflow, rsize, tsize; - int64_t sz; + off_t oflow, rsize, sz, tsize; + uint64_t usz; int ch, error, fd, oflags; char *fname, *rname; fd = -1; rsize = tsize = sz = 0; error = 0; rname = NULL; while ((ch = getopt(argc, argv, "cr:s:")) != -1) switch (ch) { case 'c': no_create = 1; break; case 'r': do_refer = 1; rname = optarg; break; case 's': - if (expand_number(optarg, &sz) == -1) + do_relative = *optarg == '+' || *optarg == '-'; + if (expand_number(do_relative ? optarg + 1 : optarg, + &usz) == -1 || (off_t)usz < 0) errx(EXIT_FAILURE, "invalid size argument `%s'", optarg); - if (*optarg == '+' || *optarg == '-') - do_relative = 1; + + sz = (*optarg == '-') ? -(off_t)usz : (off_t)usz; got_size = 1; break; default: usage(); /* NOTREACHED */ } argv += optind; argc -= optind; /* * Exactly one of do_refer or got_size must be specified. Since * do_relative implies got_size, do_relative and do_refer are * also mutually exclusive. See usage() for allowed invocations. */ if (do_refer + got_size != 1 || argc < 1) usage(); if (do_refer) { if (stat(rname, &sb) == -1) err(EXIT_FAILURE, "%s", rname); tsize = sb.st_size; } else if (do_relative) rsize = sz; else 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) { 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 (tsize < 0) tsize = 0; if (ftruncate(fd, tsize) == -1) { warn("%s", fname); error++; continue; } } if (fd != -1) close(fd); return error ? EXIT_FAILURE : EXIT_SUCCESS; } static void usage(void) { fprintf(stderr, "%s\n%s\n", "usage: truncate [-c] -s [+|-]size[K|k|M|m|G|g|T|t] file ...", " truncate [-c] -r rfile file ..."); exit(EXIT_FAILURE); } Index: stable/10 =================================================================== --- stable/10 (revision 275584) +++ stable/10 (revision 275585) Property changes on: stable/10 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r267265