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