Home | History | Annotate | Download | only in other
      1 /* truncate.c - set file length, extending sparsely if necessary
      2  *
      3  * Copyright 2011 Rob Landley <rob (at) landley.net>
      4 
      5 USE_TRUNCATE(NEWTOY(truncate, "<1s:|c", TOYFLAG_BIN))
      6 
      7 config 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 
     26 GLOBALS(
     27   char *s;
     28 
     29   long size;
     30   int type;
     31 )
     32 
     33 static 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 
     54 void 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