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