toybox/toys/other/truncate.c
<<
>>
Prefs
   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_USR|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 = !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