diff options
Diffstat (limited to 'toys/other')
-rw-r--r-- | toys/other/truncate.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/toys/other/truncate.c b/toys/other/truncate.c index d09818f3..2b3d4795 100644 --- a/toys/other/truncate.c +++ b/toys/other/truncate.c @@ -2,37 +2,61 @@ * * Copyright 2011 Rob Landley <rob@landley.net> -USE_TRUNCATE(NEWTOY(truncate, "<1s#|c", TOYFLAG_BIN)) +USE_TRUNCATE(NEWTOY(truncate, "<1s:|c", TOYFLAG_BIN)) config TRUNCATE bool "truncate" default y help - usage: truncate [-c] -s file... + usage: truncate [-c] -s SIZE file... Set length of file(s), extending sparsely if necessary. -c Don't create file if it doesn't exist. - -s New size + -s New size (with optional prefix and suffix) + + SIZE prefix: + add, - subtract, < shrink to, > expand to, + / block size rounding down, % block size rounding up + SIZE suffix: k=1024, m=1024^2, g=1024^3, t=1024^4, p=1024^5, e=1024^6 */ #define FOR_truncate #include "toys.h" GLOBALS( + char *s; + long size; + int type; ) static void do_truncate(int fd, char *name) { + long long size; + if (fd<0) return; - if (ftruncate(fd, TT.size)) perror_msg("'%s' to '%ld'", name, TT.size); + + if (TT.type == -1) size = TT.size; + else { + size = fdlength(fd); + if (TT.type<2) size += TT.size*(1-(2*TT.type)); + else if (TT.type<4) { + if ((TT.type==3) ? size > TT.size : size < TT.size) size = TT.size; + } else { + size = (size+(TT.type-4)*(TT.size-1))/TT.size; + size *= TT.size; + } + } + if (ftruncate(fd, size)) perror_msg("'%s' to '%lld'", name, size); } void truncate_main(void) { int cr = !(toys.optflags&1); + if (-1 != (TT.type = stridx("+-<>/%", *TT.s))) TT.s++; + TT.size = atolx(TT.s); + // Create files with mask rwrwrw. // Nonexistent files are only an error if we're supposed to create them. loopfiles_rw(toys.optargs, O_WRONLY|O_CLOEXEC|(cr ? O_CREAT : 0), 0666, cr, |