aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coreutils/split.c46
1 files changed, 29 insertions, 17 deletions
diff --git a/coreutils/split.c b/coreutils/split.c
index 86fd20437..392bf0c69 100644
--- a/coreutils/split.c
+++ b/coreutils/split.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 6 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
7 */ 7 */
8/* BB_AUDIT: not yet SUSV3 compliant; FIXME: add -bN{k,m} 8/* BB_AUDIT: SUSv3 compliant
9 * SUSv3 requirements: 9 * SUSv3 requirements:
10 * http://www.opengroup.org/onlinepubs/009695399/utilities/split.html 10 * http://www.opengroup.org/onlinepubs/009695399/utilities/split.html
11 */ 11 */
@@ -38,13 +38,16 @@ static bool next_file(char **old)
38 *curr += 1; 38 *curr += 1;
39 break; 39 break;
40 } 40 }
41 *curr = 'a';
42 i++; 41 i++;
42 if (i > suffix_len) {
43 bb_error_msg("Suffices exhausted");
44 return 1;
45 }
46 *curr = 'a';
43 } while (i <= suffix_len); 47 } while (i <= suffix_len);
44 if ((*curr == 'z') && (i == suffix_len))
45 return 1;
46 return 0; 48 return 0;
47} 49}
50
48#define SPLIT_OPT_l (1<<0) 51#define SPLIT_OPT_l (1<<0)
49#define SPLIT_OPT_b (1<<1) 52#define SPLIT_OPT_b (1<<1)
50#define SPLIT_OPT_a (1<<2) 53#define SPLIT_OPT_a (1<<2)
@@ -57,22 +60,28 @@ int split_main(int argc, char **argv)
57 char *sfx_len; 60 char *sfx_len;
58 unsigned cnt = 1000; 61 unsigned cnt = 1000;
59 char *input_file; 62 char *input_file;
63 bool ret = EXIT_SUCCESS;
64 FILE *fp;
60 65
61//XXX: FIXME opt_complementary = "+2"; /* at most 2 non-option arguments */ 66//XXX: FIXME opt_complementary = "+2"; /* at most 2 non-option arguments */
62 getopt32(argc, argv, "l:b:a:", &count_p, &count_p, &sfx_len); 67 getopt32(argc, argv, "l:b:a:", &count_p, &count_p, &sfx_len);
63 argv += optind; 68 argv += optind;
64 69
65 if (option_mask32 & (SPLIT_OPT_l|SPLIT_OPT_b)) 70 if (option_mask32 & SPLIT_OPT_l)
66 cnt = xatoi(count_p); 71 cnt = xatoi(count_p);
72 if (option_mask32 & SPLIT_OPT_b)
73 cnt = xatoul_sfx(count_p, split_suffices);
67 if (option_mask32 & SPLIT_OPT_a) 74 if (option_mask32 & SPLIT_OPT_a)
68 suffix_len = xatoul(sfx_len); 75 suffix_len = xatoi(sfx_len);
69 76
70 if (!*argv) 77 if (!*argv)
71 *--argv = (char*) "-"; 78 *--argv = (char*) "-";
72 input_file = *argv; 79 input_file = *argv;
80
73 if (NAME_MAX < strlen(*argv) + suffix_len) 81 if (NAME_MAX < strlen(*argv) + suffix_len)
74 bb_error_msg_and_die("Suffix too long"); 82 bb_error_msg_and_die("Suffix too long");
75 83
84 fp = fopen_or_warn_stdin(input_file);
76 { 85 {
77 char *char_p = xzalloc(suffix_len); 86 char *char_p = xzalloc(suffix_len);
78 memset(char_p, 'a', suffix_len); 87 memset(char_p, 'a', suffix_len);
@@ -85,8 +94,9 @@ int split_main(int argc, char **argv)
85 char *buf; 94 char *buf;
86 ssize_t i; 95 ssize_t i;
87 ssize_t bytes = 0; 96 ssize_t bytes = 0;
88 int inp = xopen(input_file, O_RDONLY);
89 int flags = O_WRONLY | O_CREAT | O_TRUNC; 97 int flags = O_WRONLY | O_CREAT | O_TRUNC;
98 int inp = fileno(fp);
99
90 do { 100 do {
91 int out = xopen(pfx, flags); 101 int out = xopen(pfx, flags);
92 buf = xzalloc(cnt); 102 buf = xzalloc(cnt);
@@ -95,11 +105,12 @@ int split_main(int argc, char **argv)
95 xwrite(out, buf, i); 105 xwrite(out, buf, i);
96 close(out); 106 close(out);
97 free(buf); 107 free(buf);
98 if (next_file(&pfx)) 108 if (next_file(&pfx)) {
99 flags = O_WRONLY | O_APPEND; 109 ret++;
100 } while(i > 0); 110 goto bail;
111 }
112 } while (i == cnt); /* if we read less than cnt, then nothing is left */
101 } else { /* -l */ 113 } else { /* -l */
102 FILE *fp = fopen_or_warn_stdin(input_file);
103 char *buf; 114 char *buf;
104 do { 115 do {
105 unsigned i = cnt; 116 unsigned i = cnt;
@@ -115,15 +126,16 @@ int split_main(int argc, char **argv)
115 }; 126 };
116 close(out); 127 close(out);
117 128
118 if (next_file(&pfx)) 129 if (next_file(&pfx)) {
119 flags = O_WRONLY | O_APPEND; 130 ret++;
131 goto bail;
132 }
120 } while (buf); 133 } while (buf);
121 if (ENABLE_FEATURE_CLEAN_UP)
122 fclose_if_not_stdin(fp);
123 } 134 }
124 135bail:
125 if (ENABLE_FEATURE_CLEAN_UP) { 136 if (ENABLE_FEATURE_CLEAN_UP) {
126 free(pfx); 137 free(pfx);
138 fclose_if_not_stdin(fp);
127 } 139 }
128 return EXIT_SUCCESS; 140 return ret;
129} 141}