1/* truncate.c - set file length, extending sparsely if necessary 2 * 3 * Copyright 2011 Rob Landley <rob@landley.net> 4 5USE_TRUNCATE(NEWTOY(truncate, "<1s:|c", TOYFLAG_BIN)) 6 7config TRUNCATE 8 bool "truncate" 9 default y 10 help 11 usage: truncate [-c] -s SIZE file... 12 13 Set length of file(s), extending sparsely if necessary. 14 15 -c Don't create file if it doesn't exist 16 -s New size (with optional prefix and suffix) 17 18 SIZE prefix: + add, - subtract, < shrink to, > expand to, 19 / multiple rounding down, % multiple rounding up 20 SIZE suffix: k=1024, m=1024^2, g=1024^3, t=1024^4, p=1024^5, e=1024^6 21*/ 22 23#define FOR_truncate 24#include "toys.h" 25 26GLOBALS( 27 char *s; 28 29 long size; 30 int type; 31) 32 33static void do_truncate(int fd, char *name) 34{ 35 long long size; 36 37 if (fd<0) return; 38 39 if (TT.type == -1) size = TT.size; 40 else { 41 size = fdlength(fd); 42 if (TT.type<2) size += TT.size*(1-(2*TT.type)); 43 else if (TT.type<4) { 44 if ((TT.type==2) ? (size <= TT.size) : (size >= TT.size)) return; 45 size = TT.size; 46 } else { 47 size = (size+(TT.type-4)*(TT.size-1))/TT.size; 48 size *= TT.size; 49 } 50 } 51 if (ftruncate(fd, size)) perror_msg("'%s' to '%lld'", name, size); 52} 53 54void truncate_main(void) 55{ 56 int cr = !(toys.optflags&FLAG_c); 57 58 if (-1 != (TT.type = stridx("+-<>/%", *TT.s))) TT.s++; 59 TT.size = atolx(TT.s); 60 61 // Create files with mask rwrwrw. 62 // Nonexistent files are only an error if we're supposed to create them. 63 loopfiles_rw(toys.optargs, O_WRONLY|O_CLOEXEC|(cr ? O_CREAT|WARN_ONLY : 0), 64 0666, do_truncate); 65} 66