Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Jul 2018 19:03:30 +0000 (UTC)
From:      Emmanuel Vadot <manu@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r336140 - in head/usr.bin/truncate: . tests
Message-ID:  <201807091903.w69J3Uha096804@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: manu
Date: Mon Jul  9 19:03:30 2018
New Revision: 336140
URL: https://svnweb.freebsd.org/changeset/base/336140

Log:
  truncate: Add support for -s % and /
  
  % round up to the multiple size and / round down
  This is compatible with gnu truncate.
  Add tests and document in the man page.

Modified:
  head/usr.bin/truncate/tests/truncate_test.sh
  head/usr.bin/truncate/truncate.1
  head/usr.bin/truncate/truncate.c

Modified: head/usr.bin/truncate/tests/truncate_test.sh
==============================================================================
--- head/usr.bin/truncate/tests/truncate_test.sh	Mon Jul  9 19:02:05 2018	(r336139)
+++ head/usr.bin/truncate/tests/truncate_test.sh	Mon Jul  9 19:03:30 2018	(r336140)
@@ -57,7 +57,7 @@ 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 ..."
+	    "usage: truncate [-c] -s [+|-|%|/]size[K|k|M|m|G|g|T|t] file ..."
 	_custom_create_file print "       truncate [-c] -r rfile file ..."
 }
 
@@ -378,6 +378,66 @@ negative_body()
 	[ ${st_size} -eq 0 ] || atf_fail "new file should now be zero bytes"
 }
 
+atf_test_case roundup
+roundup_head()
+{
+	atf_set "descr" "Verifies truncate round up"
+}
+roundup_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 roundup.
+	atf_check -e file:stderr.txt truncate -s%100 afile
+	eval $(stat -s afile)
+	[ ${st_size} -eq 100 ] || atf_fail "new file should now be 100 bytes"
+}
+
+atf_test_case rounddown
+rounddown_head()
+{
+	atf_set "descr" "Verifies truncate round down"
+}
+rounddown_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 2 byte roundup.
+	atf_check -e file:stderr.txt truncate -s/2 afile
+	eval $(stat -s afile)
+	[ ${st_size} -eq 4 ] || atf_fail "new file should now be 4 bytes"
+}
+
+atf_test_case rounddown_zero
+rounddown_zero_head()
+{
+	atf_set "descr" "Verifies truncate round down to zero"
+}
+rounddown_zero_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 10 byte roundup.
+	atf_check -e file:stderr.txt truncate -s/10 afile
+	eval $(stat -s afile)
+	[ ${st_size} -eq 0 ] || atf_fail "new file should now be 0 bytes"
+}
+
 atf_init_test_cases()
 {
 	atf_add_test_case illegal_option
@@ -396,4 +456,7 @@ atf_init_test_cases()
 	atf_add_test_case reference
 	atf_add_test_case new_zero
 	atf_add_test_case negative
+	atf_add_test_case roundup
+	atf_add_test_case rounddown
+	atf_add_test_case rounddown_zero
 }

Modified: head/usr.bin/truncate/truncate.1
==============================================================================
--- head/usr.bin/truncate/truncate.1	Mon Jul  9 19:02:05 2018	(r336139)
+++ head/usr.bin/truncate/truncate.1	Mon Jul  9 19:03:30 2018	(r336140)
@@ -37,7 +37,7 @@
 .Bk -words
 .Fl s Xo
 .Sm off
-.Op Cm + | -
+.Op Cm + | - | % | /
 .Ar size
 .Op Cm K | k | M | m | G | g | T | t
 .Sm on
@@ -69,7 +69,7 @@ Truncate or extend files to the length of the file
 .Ar rfile .
 .It Fl s Xo
 .Sm off
-.Op Cm + | -
+.Op Cm + | - | % | /
 .Ar size
 .Op Cm K | k | M | m | G | g | T | t
 .Sm on
@@ -84,6 +84,17 @@ If the
 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

Modified: head/usr.bin/truncate/truncate.c
==============================================================================
--- head/usr.bin/truncate/truncate.c	Mon Jul  9 19:02:05 2018	(r336139)
+++ head/usr.bin/truncate/truncate.c	Mon Jul  9 19:03:30 2018	(r336140)
@@ -56,13 +56,15 @@ main(int argc, char **argv)
 	int ch, error, fd, oflags;
 	int no_create;
 	int do_relative;
+	int do_round;
 	int do_refer;
 	int got_size;
+	int round;
 	char *fname, *rname;
 
 	fd = -1;
 	rsize = tsize = sz = 0;
-	no_create = do_relative = do_refer = got_size = 0;
+	no_create = do_relative = do_round = do_refer = got_size = 0;
 	error = 0;
 	rname = NULL;
 	while ((ch = getopt(argc, argv, "cr:s:")) != -1)
@@ -75,13 +77,19 @@ main(int argc, char **argv)
 			rname = optarg;
 			break;
 		case 's':
-			do_relative = *optarg == '+' || *optarg == '-';
-			if (expand_number(do_relative ? optarg + 1 : optarg,
+			if (*optarg == '+' || *optarg == '-') {
+				do_relative = 1;
+			} else if (*optarg == '%' || *optarg == '/') {
+				do_round = 1;
+			}
+			if (expand_number(do_relative || do_round ?
+			    optarg + 1 : optarg,
 			    &usz) == -1 || (off_t)usz < 0)
 				errx(EXIT_FAILURE,
 				    "invalid size argument `%s'", optarg);
 
-			sz = (*optarg == '-') ? -(off_t)usz : (off_t)usz;
+			sz = (*optarg == '-' || *optarg == '/') ?
+				-(off_t)usz : (off_t)usz;
 			got_size = 1;
 			break;
 		default:
@@ -103,7 +111,7 @@ main(int argc, char **argv)
 		if (stat(rname, &sb) == -1)
 			err(EXIT_FAILURE, "%s", rname);
 		tsize = sb.st_size;
-	} else if (do_relative)
+	} else if (do_relative || do_round)
 		rsize = sz;
 	else
 		tsize = sz;
@@ -139,6 +147,25 @@ main(int argc, char **argv)
 			}
 			tsize = oflow;
 		}
+		if (do_round) {
+			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 (round != sz && rsize < 0)
+					round--;
+				else if (rsize > 0)
+					round++;
+				tsize = (round < 0 ? 0 : round) * sz;
+			} else
+				tsize = sb.st_size;
+		}
 		if (tsize < 0)
 			tsize = 0;
 
@@ -158,7 +185,7 @@ static void
 usage(void)
 {
 	fprintf(stderr, "%s\n%s\n",
-	    "usage: truncate [-c] -s [+|-]size[K|k|M|m|G|g|T|t] file ...",
+	    "usage: truncate [-c] -s [+|-|%|/]size[K|k|M|m|G|g|T|t] file ...",
 	    "       truncate [-c] -r rfile file ...");
 	exit(EXIT_FAILURE);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807091903.w69J3Uha096804>