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.
This commit is contained in:
parent
930c5c942c
commit
76772b9dc3
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
@ -85,6 +85,17 @@ 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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user