Mercurial > hg > toybox
annotate toys/posix/split.c @ 1775:57f2a26fa92c draft toast
To ensure that toybox can be installed alongside busybox without
confusing update-alternatives, the paths of the links installed by toybox should
match those installed by busybox. This is accomplished by changing the flags
of a few tools within toybox.
author | Paul Barker <paul@paulbarker.me.uk> |
---|---|
date | Sat, 04 Apr 2015 11:58:06 -0500 |
parents | 59a3fd32329c |
children |
rev | line source |
---|---|
924 | 1 /* split.c - split a file into smaller files |
2 * | |
3 * Copyright 2013 Rob Landley <rob@landley.net> | |
4 * | |
5 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/split.html | |
6 * | |
7 * Standard does not cover: | |
8 * - should splitting an empty file produce an empty outfile? (Went with "no".) | |
9 * - permissions on output file | |
10 | |
11 USE_SPLIT(NEWTOY(split, ">2a#<1=2>9b#<1l#<1", TOYFLAG_USR|TOYFLAG_BIN)) | |
12 | |
13 config SPLIT | |
14 bool "split" | |
15 default y | |
16 help | |
17 usage: split [-a SUFFIX_LEN] [-b BYTES] [-l LINES] [INPUT [OUTPUT]] | |
18 | |
19 Copy INPUT (or stdin) data to a series of OUTPUT (or "x") files with | |
20 alphabetically increasing suffix (aa, ab, ac... az, ba, bb...). | |
21 | |
22 -a Suffix length (default 2) | |
23 -b BYTES/file (10, 10k, 10m, 10g...) | |
24 -l LINES/file (default 1000) | |
25 */ | |
26 | |
27 #define FOR_split | |
28 #include "toys.h" | |
29 | |
30 GLOBALS( | |
31 long lines; | |
32 long bytes; | |
33 long suflen; | |
34 | |
35 char *outfile; | |
36 ) | |
37 | |
38 void do_split(int infd, char *in) | |
39 { | |
40 unsigned long bytesleft, linesleft, filenum, len, pos; | |
41 int outfd = -1; | |
42 struct stat st; | |
43 | |
44 // posix doesn't cover permissions on output file, so copy input (or 0777) | |
45 st.st_mode = 0777; | |
46 fstat(infd, &st); | |
47 | |
48 len = pos = filenum = bytesleft = linesleft = 0; | |
49 for (;;) { | |
50 int i, j; | |
51 | |
52 // Refill toybuf? | |
53 if (len == pos) { | |
54 if (!(len = xread(infd, toybuf, sizeof(toybuf)))) break; | |
55 pos = 0; | |
56 } | |
57 | |
58 // Start new output file? | |
59 if ((TT.bytes && !bytesleft) || (TT.lines && !linesleft)) { | |
60 char *s = TT.outfile + strlen(TT.outfile); | |
61 | |
62 j = filenum++; | |
63 for (i = 0; i<TT.suflen; i++) { | |
64 *(--s) = 'a'+(j%26); | |
65 j /= 26; | |
66 } | |
67 if (j) error_exit("bad suffix"); | |
68 bytesleft = TT.bytes; | |
69 linesleft = TT.lines; | |
70 if (outfd != -1) close(outfd); | |
71 outfd = xcreate(TT.outfile, O_RDWR|O_CREAT|O_TRUNC, st.st_mode & 0777); | |
72 } | |
73 | |
74 // Write next chunk of output. | |
75 if (TT.lines) { | |
76 for (i = pos; i < len; ) { | |
77 if (toybuf[i++] == '\n' && !--linesleft) break; | |
78 if (!--bytesleft) break; | |
79 } | |
80 j = i - pos; | |
81 } else { | |
82 j = len - pos; | |
83 if (j > bytesleft) j = bytesleft; | |
84 bytesleft -= j; | |
85 } | |
86 xwrite(outfd, toybuf+pos, j); | |
87 pos += j; | |
88 } | |
89 | |
90 if (CFG_TOYBOX_FREE) { | |
91 if (outfd != -1) close(outfd); | |
92 if (infd) close(infd); | |
93 free(TT.outfile); | |
94 } | |
95 xexit(); | |
96 } | |
97 | |
98 void split_main(void) | |
99 { | |
100 if (!TT.bytes && !TT.lines) TT.lines = 1000; | |
101 | |
102 // Allocate template for output filenames | |
1712
59a3fd32329c
remove accidental space in format string
Elliott Hughes <enh@google.com>
parents:
1183
diff
changeset
|
103 TT.outfile = xmprintf("%s%*c", (toys.optc == 2) ? toys.optargs[1] : "x", |
924 | 104 (int)TT.suflen, ' '); |
105 | |
106 // We only ever use one input, but this handles '-' or no input for us. | |
107 loopfiles(toys.optargs, do_split); | |
108 } |