aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2013-08-27 16:10:53 +0100
committerRon Yorston <rmy@pobox.com>2013-08-27 16:10:53 +0100
commit3fd34651ea72ea1c335d3170f234cb0517fd897f (patch)
tree36e8fc40cffd464ffda4759020777dd3ca23ca31 /coreutils
parente3ac39098326de084a805d0dd31db9666b734f20 (diff)
parentd6ae4fb446daedfe3073d67be655942e9fa7eb18 (diff)
downloadbusybox-w32-3fd34651ea72ea1c335d3170f234cb0517fd897f.tar.gz
busybox-w32-3fd34651ea72ea1c335d3170f234cb0517fd897f.tar.bz2
busybox-w32-3fd34651ea72ea1c335d3170f234cb0517fd897f.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/catv.c43
-rw-r--r--coreutils/dd.c115
-rw-r--r--coreutils/head.c4
-rw-r--r--coreutils/head_tail.c14
-rw-r--r--coreutils/head_tail.h6
-rw-r--r--coreutils/md5_sha1_sum.c4
-rw-r--r--coreutils/od_bloaty.c12
-rw-r--r--coreutils/split.c11
-rw-r--r--coreutils/stty.c105
-rw-r--r--coreutils/tail.c27
10 files changed, 167 insertions, 174 deletions
diff --git a/coreutils/catv.c b/coreutils/catv.c
index 214b4311a..e3499c597 100644
--- a/coreutils/catv.c
+++ b/coreutils/catv.c
@@ -25,14 +25,23 @@ int catv_main(int argc UNUSED_PARAM, char **argv)
25{ 25{
26 int retval = EXIT_SUCCESS; 26 int retval = EXIT_SUCCESS;
27 int fd; 27 int fd;
28 unsigned flags; 28 unsigned opts;
29
30 flags = getopt32(argv, "etv");
31#define CATV_OPT_e (1<<0) 29#define CATV_OPT_e (1<<0)
32#define CATV_OPT_t (1<<1) 30#define CATV_OPT_t (1<<1)
33#define CATV_OPT_v (1<<2) 31#define CATV_OPT_v (1<<2)
34 flags ^= CATV_OPT_v; 32 typedef char BUG_const_mismatch[
33 CATV_OPT_e == VISIBLE_ENDLINE && CATV_OPT_t == VISIBLE_SHOW_TABS
34 ? 1 : -1
35 ];
36
37 opts = getopt32(argv, "etv");
35 argv += optind; 38 argv += optind;
39#if 0 /* These consts match, we can just pass "opts" to visible() */
40 if (opts & CATV_OPT_e)
41 flags |= VISIBLE_ENDLINE;
42 if (opts & CATV_OPT_t)
43 flags |= VISIBLE_SHOW_TABS;
44#endif
36 45
37 /* Read from stdin if there's nothing else to do. */ 46 /* Read from stdin if there's nothing else to do. */
38 if (!argv[0]) 47 if (!argv[0])
@@ -50,29 +59,17 @@ int catv_main(int argc UNUSED_PARAM, char **argv)
50 res = read(fd, read_buf, COMMON_BUFSIZE); 59 res = read(fd, read_buf, COMMON_BUFSIZE);
51 if (res < 0) 60 if (res < 0)
52 retval = EXIT_FAILURE; 61 retval = EXIT_FAILURE;
53 if (res < 1) 62 if (res <= 0)
54 break; 63 break;
55 for (i = 0; i < res; i++) { 64 for (i = 0; i < res; i++) {
56 unsigned char c = read_buf[i]; 65 unsigned char c = read_buf[i];
57 66 if (opts & CATV_OPT_v) {
58 if (c > 126 && (flags & CATV_OPT_v)) { 67 putchar(c);
59 if (c == 127) { 68 } else {
60 printf("^?"); 69 char buf[sizeof("M-^c")];
61 continue; 70 visible(c, buf, opts);
62 } 71 fputs(buf, stdout);
63 printf("M-");
64 c -= 128;
65 }
66 if (c < 32) {
67 if (c == 10) {
68 if (flags & CATV_OPT_e)
69 bb_putchar('$');
70 } else if (flags & (c==9 ? CATV_OPT_t : CATV_OPT_v)) {
71 printf("^%c", c+'@');
72 continue;
73 }
74 } 72 }
75 bb_putchar(c);
76 } 73 }
77 } 74 }
78 if (ENABLE_FEATURE_CLEAN_UP && fd) 75 if (ENABLE_FEATURE_CLEAN_UP && fd)
diff --git a/coreutils/dd.c b/coreutils/dd.c
index f6869cb26..db61f665e 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -30,10 +30,10 @@
30//usage: "\n conv=noerror Continue after read errors" 30//usage: "\n conv=noerror Continue after read errors"
31//usage: "\n conv=sync Pad blocks with zeros" 31//usage: "\n conv=sync Pad blocks with zeros"
32//usage: "\n conv=fsync Physically write data out before finishing" 32//usage: "\n conv=fsync Physically write data out before finishing"
33//usage: "\n conv=swab Swap every pair of bytes"
33//usage: ) 34//usage: )
34//usage: "\n" 35//usage: "\n"
35//usage: "\nNumbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024)," 36//usage: "\nN may be suffixed by c (1), w (2), b (512), kD (1000), k (1024), MD, M, GD, G"
36//usage: "\nMD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)"
37//usage: 37//usage:
38//usage:#define dd_example_usage 38//usage:#define dd_example_usage
39//usage: "$ dd if=/dev/zero of=/dev/ram1 bs=1M count=4\n" 39//usage: "$ dd if=/dev/zero of=/dev/ram1 bs=1M count=4\n"
@@ -151,13 +151,14 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
151 enum { 151 enum {
152 /* Must be in the same order as OP_conv_XXX! */ 152 /* Must be in the same order as OP_conv_XXX! */
153 /* (see "flags |= (1 << what)" below) */ 153 /* (see "flags |= (1 << what)" below) */
154 FLAG_NOTRUNC = 1 << 0, 154 FLAG_NOTRUNC = (1 << 0) * ENABLE_FEATURE_DD_IBS_OBS,
155 FLAG_SYNC = 1 << 1, 155 FLAG_SYNC = (1 << 1) * ENABLE_FEATURE_DD_IBS_OBS,
156 FLAG_NOERROR = 1 << 2, 156 FLAG_NOERROR = (1 << 2) * ENABLE_FEATURE_DD_IBS_OBS,
157 FLAG_FSYNC = 1 << 3, 157 FLAG_FSYNC = (1 << 3) * ENABLE_FEATURE_DD_IBS_OBS,
158 FLAG_SWAB = (1 << 4) * ENABLE_FEATURE_DD_IBS_OBS,
158 /* end of conv flags */ 159 /* end of conv flags */
159 FLAG_TWOBUFS = 1 << 4, 160 FLAG_TWOBUFS = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS,
160 FLAG_COUNT = 1 << 5, 161 FLAG_COUNT = 1 << 6,
161 }; 162 };
162 static const char keywords[] ALIGN1 = 163 static const char keywords[] ALIGN1 =
163 "bs\0""count\0""seek\0""skip\0""if\0""of\0" 164 "bs\0""count\0""seek\0""skip\0""if\0""of\0"
@@ -167,7 +168,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
167 ; 168 ;
168#if ENABLE_FEATURE_DD_IBS_OBS 169#if ENABLE_FEATURE_DD_IBS_OBS
169 static const char conv_words[] ALIGN1 = 170 static const char conv_words[] ALIGN1 =
170 "notrunc\0""sync\0""noerror\0""fsync\0"; 171 "notrunc\0""sync\0""noerror\0""fsync\0""swab\0";
171#endif 172#endif
172 enum { 173 enum {
173 OP_bs = 0, 174 OP_bs = 0,
@@ -185,11 +186,11 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
185 OP_conv_sync, 186 OP_conv_sync,
186 OP_conv_noerror, 187 OP_conv_noerror,
187 OP_conv_fsync, 188 OP_conv_fsync,
189 OP_conv_swab,
188 /* Unimplemented conv=XXX: */ 190 /* Unimplemented conv=XXX: */
189 //nocreat do not create the output file 191 //nocreat do not create the output file
190 //excl fail if the output file already exists 192 //excl fail if the output file already exists
191 //fdatasync physically write output file data before finishing 193 //fdatasync physically write output file data before finishing
192 //swab swap every pair of input bytes
193 //lcase change upper case to lower case 194 //lcase change upper case to lower case
194 //ucase change lower case to upper case 195 //ucase change lower case to upper case
195 //block pad newline-terminated records with spaces to cbs-size 196 //block pad newline-terminated records with spaces to cbs-size
@@ -197,23 +198,34 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
197 //ascii from EBCDIC to ASCII 198 //ascii from EBCDIC to ASCII
198 //ebcdic from ASCII to EBCDIC 199 //ebcdic from ASCII to EBCDIC
199 //ibm from ASCII to alternate EBCDIC 200 //ibm from ASCII to alternate EBCDIC
201 /* Partially implemented: */
202 //swab swap every pair of input bytes: will abort on non-even reads
200#endif 203#endif
201 }; 204 };
202 int exitcode = EXIT_FAILURE; 205 smallint exitcode = EXIT_FAILURE;
203 int devzero = 0; 206 int devzero = 0;
204 size_t ibs = 512, obs = 512; 207 int i;
205 ssize_t n, w; 208 size_t ibs = 512;
206 char *ibuf, *obuf; 209 char *ibuf;
207 /* And these are all zeroed at once! */ 210#if ENABLE_FEATURE_DD_IBS_OBS
211 size_t obs = 512;
212 char *obuf;
213#else
214# define obs ibs
215# define obuf ibuf
216#endif
217 /* These are all zeroed at once! */
208 struct { 218 struct {
209 int flags; 219 int flags;
210 size_t oc; 220 size_t oc;
221 ssize_t prev_read_size; /* for detecting swab failure */
211 off_t count; 222 off_t count;
212 off_t seek, skip; 223 off_t seek, skip;
213 const char *infile, *outfile; 224 const char *infile, *outfile;
214 } Z; 225 } Z;
215#define flags (Z.flags ) 226#define flags (Z.flags )
216#define oc (Z.oc ) 227#define oc (Z.oc )
228#define prev_read_size (Z.prev_read_size)
217#define count (Z.count ) 229#define count (Z.count )
218#define seek (Z.seek ) 230#define seek (Z.seek )
219#define skip (Z.skip ) 231#define skip (Z.skip )
@@ -224,10 +236,10 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
224 INIT_G(); 236 INIT_G();
225 //fflush_all(); - is this needed because of NOEXEC? 237 //fflush_all(); - is this needed because of NOEXEC?
226 238
227 for (n = 1; argv[n]; n++) { 239 for (i = 1; argv[i]; i++) {
228 int what; 240 int what;
229 char *val; 241 char *val;
230 char *arg = argv[n]; 242 char *arg = argv[i];
231 243
232#if ENABLE_DESKTOP 244#if ENABLE_DESKTOP
233 /* "dd --". NB: coreutils 6.9 will complain if they see 245 /* "dd --". NB: coreutils 6.9 will complain if they see
@@ -256,6 +268,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
256 } 268 }
257 if (what == OP_conv) { 269 if (what == OP_conv) {
258 while (1) { 270 while (1) {
271 int n;
259 /* find ',', replace them with NUL so we can use val for 272 /* find ',', replace them with NUL so we can use val for
260 * index_in_strings() without copying. 273 * index_in_strings() without copying.
261 * We rely on val being non-null, else strchr would fault. 274 * We rely on val being non-null, else strchr would fault.
@@ -263,20 +276,21 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
263 arg = strchr(val, ','); 276 arg = strchr(val, ',');
264 if (arg) 277 if (arg)
265 *arg = '\0'; 278 *arg = '\0';
266 what = index_in_strings(conv_words, val); 279 n = index_in_strings(conv_words, val);
267 if (what < 0) 280 if (n < 0)
268 bb_error_msg_and_die(bb_msg_invalid_arg, val, "conv"); 281 bb_error_msg_and_die(bb_msg_invalid_arg, val, "conv");
269 flags |= (1 << what); 282 flags |= (1 << n);
270 if (!arg) /* no ',' left, so this was the last specifier */ 283 if (!arg) /* no ',' left, so this was the last specifier */
271 break; 284 break;
272 /* *arg = ','; - to preserve ps listing? */ 285 /* *arg = ','; - to preserve ps listing? */
273 val = arg + 1; /* skip this keyword and ',' */ 286 val = arg + 1; /* skip this keyword and ',' */
274 } 287 }
275 continue; /* we trashed 'what', can't fall through */ 288 /*continue;*/
276 } 289 }
277#endif 290#endif
278 if (what == OP_bs) { 291 if (what == OP_bs) {
279 ibs = obs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, dd_suffixes); 292 ibs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, dd_suffixes);
293 obs = ibs;
280 /*continue;*/ 294 /*continue;*/
281 } 295 }
282 /* These can be large: */ 296 /* These can be large: */
@@ -301,14 +315,17 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
301 outfile = val; 315 outfile = val;
302 /*continue;*/ 316 /*continue;*/
303 } 317 }
304 } /* end of "for (argv[n])" */ 318 } /* end of "for (argv[i])" */
305 319
306//XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever 320//XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever
307 ibuf = obuf = xmalloc(ibs); 321 ibuf = xmalloc(ibs);
322 obuf = ibuf;
323#if ENABLE_FEATURE_DD_IBS_OBS
308 if (ibs != obs) { 324 if (ibs != obs) {
309 flags |= FLAG_TWOBUFS; 325 flags |= FLAG_TWOBUFS;
310 obuf = xmalloc(obs); 326 obuf = xmalloc(obs);
311 } 327 }
328#endif
312 329
313#if ENABLE_FEATURE_DD_SIGNAL_HANDLING 330#if ENABLE_FEATURE_DD_SIGNAL_HANDLING
314 signal_SA_RESTART_empty_mask(SIGUSR1, dd_output_status); 331 signal_SA_RESTART_empty_mask(SIGUSR1, dd_output_status);
@@ -317,17 +334,17 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
317 G.begin_time_us = monotonic_us(); 334 G.begin_time_us = monotonic_us();
318#endif 335#endif
319 336
320 if (infile != NULL) 337 if (infile) {
321 if (ENABLE_PLATFORM_MINGW32 && !strcmp(infile, "/dev/zero")) { 338 if (ENABLE_PLATFORM_MINGW32 && !strcmp(infile, "/dev/zero")) {
322 flags |= FLAG_NOERROR; 339 flags |= FLAG_NOERROR;
323 devzero = 1; 340 devzero = 1;
324 } 341 } else {
325 else
326 xmove_fd(xopen(infile, O_RDONLY), ifd); 342 xmove_fd(xopen(infile, O_RDONLY), ifd);
327 else { 343 }
344 } else {
328 infile = bb_msg_standard_input; 345 infile = bb_msg_standard_input;
329 } 346 }
330 if (outfile != NULL) { 347 if (outfile) {
331 int oflag = O_WRONLY | O_CREAT; 348 int oflag = O_WRONLY | O_CREAT;
332 349
333 if (!seek && !(flags & FLAG_NOTRUNC)) 350 if (!seek && !(flags & FLAG_NOTRUNC))
@@ -352,13 +369,13 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
352 } 369 }
353 if (skip && !devzero) { 370 if (skip && !devzero) {
354 if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) { 371 if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) {
355 while (skip-- > 0) { 372 do {
356 n = safe_read(ifd, ibuf, ibs); 373 ssize_t n = safe_read(ifd, ibuf, ibs);
357 if (n < 0) 374 if (n < 0)
358 goto die_infile; 375 goto die_infile;
359 if (n == 0) 376 if (n == 0)
360 break; 377 break;
361 } 378 } while (--skip != 0);
362 } 379 }
363 } 380 }
364 if (seek) { 381 if (seek) {
@@ -367,6 +384,8 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
367 } 384 }
368 385
369 while (!(flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) { 386 while (!(flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) {
387 ssize_t n;
388
370 if (devzero) { 389 if (devzero) {
371 memset(ibuf, 0, ibs); 390 memset(ibuf, 0, ibs);
372 n = ibs; 391 n = ibs;
@@ -386,6 +405,27 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
386 * conv=noerror just ignores input bad blocks */ 405 * conv=noerror just ignores input bad blocks */
387 n = 0; 406 n = 0;
388 } 407 }
408 if (flags & FLAG_SWAB) {
409 uint16_t *p16;
410 ssize_t n2;
411
412 /* Our code allows only last read to be odd-sized */
413 if (prev_read_size & 1)
414 bb_error_msg_and_die("can't swab %lu byte buffer",
415 (unsigned long)prev_read_size);
416 prev_read_size = n;
417
418 /* If n is odd, last byte is not swapped:
419 * echo -n "qwe" | dd conv=swab
420 * prints "wqe".
421 */
422 p16 = (void*) ibuf;
423 n2 = (n >> 1);
424 while (--n2 >= 0) {
425 *p16 = bswap_16(*p16);
426 p16++;
427 }
428 }
389 if ((size_t)n == ibs) 429 if ((size_t)n == ibs)
390 G.in_full++; 430 G.in_full++;
391 else { 431 else {
@@ -412,8 +452,10 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
412 oc = 0; 452 oc = 0;
413 } 453 }
414 } 454 }
415 } else if (write_and_stats(ibuf, n, obs, outfile)) 455 } else {
416 goto out_status; 456 if (write_and_stats(ibuf, n, obs, outfile))
457 goto out_status;
458 }
417 459
418 if (flags & FLAG_FSYNC) { 460 if (flags & FLAG_FSYNC) {
419 if (fsync(ofd) < 0) 461 if (fsync(ofd) < 0)
@@ -422,9 +464,8 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
422 } 464 }
423 465
424 if (ENABLE_FEATURE_DD_IBS_OBS && oc) { 466 if (ENABLE_FEATURE_DD_IBS_OBS && oc) {
425 w = full_write_or_warn(obuf, oc, outfile); 467 if (write_and_stats(obuf, oc, obs, outfile))
426 if (w < 0) goto out_status; 468 goto out_status;
427 if (w > 0) G.out_part++;
428 } 469 }
429 470
430 if (!devzero && close(ifd) < 0) { 471 if (!devzero && close(ifd) < 0) {
diff --git a/coreutils/head.c b/coreutils/head.c
index 291e1ce37..9388b026a 100644
--- a/coreutils/head.c
+++ b/coreutils/head.c
@@ -12,7 +12,6 @@
12/* http://www.opengroup.org/onlinepubs/007904975/utilities/head.html */ 12/* http://www.opengroup.org/onlinepubs/007904975/utilities/head.html */
13 13
14//kbuild:lib-$(CONFIG_HEAD) += head.o 14//kbuild:lib-$(CONFIG_HEAD) += head.o
15//kbuild:lib-$(CONFIG_HEAD) += head_tail.o
16 15
17//usage:#define head_trivial_usage 16//usage:#define head_trivial_usage
18//usage: "[OPTIONS] [FILE]..." 17//usage: "[OPTIONS] [FILE]..."
@@ -35,7 +34,6 @@
35//usage: "daemon:x:1:1:daemon:/usr/sbin:/bin/sh\n" 34//usage: "daemon:x:1:1:daemon:/usr/sbin:/bin/sh\n"
36 35
37#include "libbb.h" 36#include "libbb.h"
38#include "head_tail.h"
39 37
40/* This is a NOEXEC applet. Be very careful! */ 38/* This is a NOEXEC applet. Be very careful! */
41 39
@@ -140,7 +138,7 @@ eat_num(bool *negative_N, const char *p)
140 p++; 138 p++;
141 } 139 }
142#endif 140#endif
143 return xatoul_sfx(p, head_tail_suffixes); 141 return xatoul_sfx(p, bkm_suffixes);
144} 142}
145 143
146static const char head_opts[] ALIGN1 = 144static const char head_opts[] ALIGN1 =
diff --git a/coreutils/head_tail.c b/coreutils/head_tail.c
deleted file mode 100644
index 1658c0d1b..000000000
--- a/coreutils/head_tail.c
+++ /dev/null
@@ -1,14 +0,0 @@
1/*
2 * Copyright (C) 2013 Denys Vlasenko
3 *
4 * Licensed under GPLv2, see file LICENSE in this source tree.
5 */
6#include "libbb.h"
7#include "head_tail.h"
8
9const struct suffix_mult head_tail_suffixes[] = {
10 { "b", 512 },
11 { "k", 1024 },
12 { "m", 1024*1024 },
13 { "", 0 }
14};
diff --git a/coreutils/head_tail.h b/coreutils/head_tail.h
deleted file mode 100644
index df19e41e0..000000000
--- a/coreutils/head_tail.h
+++ /dev/null
@@ -1,6 +0,0 @@
1/*
2 * Copyright (C) 2013 Denys Vlasenko
3 *
4 * Licensed under GPLv2, see file LICENSE in this source tree.
5 */
6extern const struct suffix_mult head_tail_suffixes[];
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c
index 92a4d4462..1a5342e87 100644
--- a/coreutils/md5_sha1_sum.c
+++ b/coreutils/md5_sha1_sum.c
@@ -151,7 +151,9 @@ static uint8_t *hash_file(const char *filename)
151 update(&context, in_buf, count); 151 update(&context, in_buf, count);
152 } 152 }
153 hash_value = NULL; 153 hash_value = NULL;
154 if (count == 0) { 154 if (count < 0)
155 bb_perror_msg("can't read '%s'", filename);
156 else /* count == 0 */ {
155 final(&context, in_buf); 157 final(&context, in_buf);
156 hash_value = hash_bin_to_hex(in_buf, hash_len); 158 hash_value = hash_bin_to_hex(in_buf, hash_len);
157 } 159 }
diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c
index ee4f72ca1..c4d11601f 100644
--- a/coreutils/od_bloaty.c
+++ b/coreutils/od_bloaty.c
@@ -1173,12 +1173,6 @@ parse_old_offset(const char *s, off_t *offset)
1173int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1173int od_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1174int od_main(int argc UNUSED_PARAM, char **argv) 1174int od_main(int argc UNUSED_PARAM, char **argv)
1175{ 1175{
1176 static const struct suffix_mult bkm[] = {
1177 { "b", 512 },
1178 { "k", 1024 },
1179 { "m", 1024*1024 },
1180 { "", 0 }
1181 };
1182#if ENABLE_LONG_OPTS 1176#if ENABLE_LONG_OPTS
1183 static const char od_longopts[] ALIGN1 = 1177 static const char od_longopts[] ALIGN1 =
1184 "skip-bytes\0" Required_argument "j" 1178 "skip-bytes\0" Required_argument "j"
@@ -1237,7 +1231,7 @@ int od_main(int argc UNUSED_PARAM, char **argv)
1237 address_pad_len_char = doxn_address_pad_len_char[pos]; 1231 address_pad_len_char = doxn_address_pad_len_char[pos];
1238 } 1232 }
1239 if (opt & OPT_N) { 1233 if (opt & OPT_N) {
1240 max_bytes_to_format = xstrtooff_sfx(str_N, 0, bkm); 1234 max_bytes_to_format = xstrtooff_sfx(str_N, 0, bkm_suffixes);
1241 } 1235 }
1242 if (opt & OPT_a) decode_format_string("a"); 1236 if (opt & OPT_a) decode_format_string("a");
1243 if (opt & OPT_b) decode_format_string("oC"); 1237 if (opt & OPT_b) decode_format_string("oC");
@@ -1246,7 +1240,7 @@ int od_main(int argc UNUSED_PARAM, char **argv)
1246 if (opt & OPT_f) decode_format_string("fF"); 1240 if (opt & OPT_f) decode_format_string("fF");
1247 if (opt & OPT_h) decode_format_string("x2"); 1241 if (opt & OPT_h) decode_format_string("x2");
1248 if (opt & OPT_i) decode_format_string("d2"); 1242 if (opt & OPT_i) decode_format_string("d2");
1249 if (opt & OPT_j) n_bytes_to_skip = xstrtooff_sfx(str_j, 0, bkm); 1243 if (opt & OPT_j) n_bytes_to_skip = xstrtooff_sfx(str_j, 0, bkm_suffixes);
1250 if (opt & OPT_l) decode_format_string("d4"); 1244 if (opt & OPT_l) decode_format_string("d4");
1251 if (opt & OPT_o) decode_format_string("o2"); 1245 if (opt & OPT_o) decode_format_string("o2");
1252 while (lst_t) { 1246 while (lst_t) {
@@ -1255,7 +1249,7 @@ int od_main(int argc UNUSED_PARAM, char **argv)
1255 if (opt & OPT_x) decode_format_string("x2"); 1249 if (opt & OPT_x) decode_format_string("x2");
1256 if (opt & OPT_s) decode_format_string("d2"); 1250 if (opt & OPT_s) decode_format_string("d2");
1257 if (opt & OPT_S) { 1251 if (opt & OPT_S) {
1258 string_min = xstrtou_sfx(str_S, 0, bkm); 1252 string_min = xstrtou_sfx(str_S, 0, bkm_suffixes);
1259 } 1253 }
1260 1254
1261 // Bloat: 1255 // Bloat:
diff --git a/coreutils/split.c b/coreutils/split.c
index 11e640442..1e1673efb 100644
--- a/coreutils/split.c
+++ b/coreutils/split.c
@@ -23,17 +23,15 @@
23 23
24#include "libbb.h" 24#include "libbb.h"
25 25
26static const struct suffix_mult split_suffices[] = {
27#if ENABLE_FEATURE_SPLIT_FANCY 26#if ENABLE_FEATURE_SPLIT_FANCY
27static const struct suffix_mult split_suffixes[] = {
28 { "b", 512 }, 28 { "b", 512 },
29#endif
30 { "k", 1024 }, 29 { "k", 1024 },
31 { "m", 1024*1024 }, 30 { "m", 1024*1024 },
32#if ENABLE_FEATURE_SPLIT_FANCY
33 { "g", 1024*1024*1024 }, 31 { "g", 1024*1024*1024 },
34#endif
35 { "", 0 } 32 { "", 0 }
36}; 33};
34#endif
37 35
38/* Increment the suffix part of the filename. 36/* Increment the suffix part of the filename.
39 * Returns NULL if we are out of filenames. 37 * Returns NULL if we are out of filenames.
@@ -86,7 +84,10 @@ int split_main(int argc UNUSED_PARAM, char **argv)
86 if (opt & SPLIT_OPT_l) 84 if (opt & SPLIT_OPT_l)
87 cnt = XATOOFF(count_p); 85 cnt = XATOOFF(count_p);
88 if (opt & SPLIT_OPT_b) // FIXME: also needs XATOOFF 86 if (opt & SPLIT_OPT_b) // FIXME: also needs XATOOFF
89 cnt = xatoull_sfx(count_p, split_suffices); 87 cnt = xatoull_sfx(count_p,
88 IF_FEATURE_SPLIT_FANCY(split_suffixes)
89 IF_NOT_FEATURE_SPLIT_FANCY(km_suffixes)
90 );
90 sfx = "x"; 91 sfx = "x";
91 92
92 argv += optind; 93 argv += optind;
diff --git a/coreutils/stty.c b/coreutils/stty.c
index 96754dd84..378a848e7 100644
--- a/coreutils/stty.c
+++ b/coreutils/stty.c
@@ -246,10 +246,21 @@ enum speed_setting {
246 246
247/* Which member(s) of 'struct termios' a mode uses */ 247/* Which member(s) of 'struct termios' a mode uses */
248enum { 248enum {
249 /* Do NOT change the order or values, as mode_type_flag()
250 * depends on them */
251 control, input, output, local, combination 249 control, input, output, local, combination
252}; 250};
251static tcflag_t *get_ptr_to_tcflag(unsigned type, const struct termios *mode)
252{
253 static const uint8_t tcflag_offsets[] ALIGN1 = {
254 offsetof(struct termios, c_cflag), /* control */
255 offsetof(struct termios, c_iflag), /* input */
256 offsetof(struct termios, c_oflag), /* output */
257 offsetof(struct termios, c_lflag) /* local */
258 };
259 if (type <= local) {
260 return (tcflag_t*) (((char*)mode) + tcflag_offsets[type]);
261 }
262 return NULL;
263}
253 264
254/* Flags for 'struct mode_info' */ 265/* Flags for 'struct mode_info' */
255#define SANE_SET 1 /* Set in 'sane' mode */ 266#define SANE_SET 1 /* Set in 'sane' mode */
@@ -770,51 +781,6 @@ struct globals {
770 G.max_col = 80; \ 781 G.max_col = 80; \
771} while (0) 782} while (0)
772 783
773
774/* Return a string that is the printable representation of character CH */
775/* Adapted from 'cat' by Torbjorn Granlund */
776static const char *visible(unsigned ch)
777{
778 char *bpout = G.buf;
779
780 if (ch == _POSIX_VDISABLE)
781 return "<undef>";
782
783 if (ch >= 128) {
784 ch -= 128;
785 *bpout++ = 'M';
786 *bpout++ = '-';
787 }
788
789 if (ch < 32) {
790 *bpout++ = '^';
791 *bpout++ = ch + 64;
792 } else if (ch < 127) {
793 *bpout++ = ch;
794 } else {
795 *bpout++ = '^';
796 *bpout++ = '?';
797 }
798
799 *bpout = '\0';
800 return G.buf;
801}
802
803static tcflag_t *mode_type_flag(unsigned type, const struct termios *mode)
804{
805 static const uint8_t tcflag_offsets[] ALIGN1 = {
806 offsetof(struct termios, c_cflag), /* control */
807 offsetof(struct termios, c_iflag), /* input */
808 offsetof(struct termios, c_oflag), /* output */
809 offsetof(struct termios, c_lflag) /* local */
810 };
811
812 if (type <= local) {
813 return (tcflag_t*) (((char*)mode) + tcflag_offsets[type]);
814 }
815 return NULL;
816}
817
818static void set_speed_or_die(enum speed_setting type, const char *arg, 784static void set_speed_or_die(enum speed_setting type, const char *arg,
819 struct termios *mode) 785 struct termios *mode)
820{ 786{
@@ -1042,6 +1008,7 @@ static void do_display(const struct termios *mode, int all)
1042#endif 1008#endif
1043 1009
1044 for (i = 0; i != CIDX_min; ++i) { 1010 for (i = 0; i != CIDX_min; ++i) {
1011 char ch;
1045 /* If swtch is the same as susp, don't print both */ 1012 /* If swtch is the same as susp, don't print both */
1046#if VSWTCH == VSUSP 1013#if VSWTCH == VSUSP
1047 if (i == CIDX_swtch) 1014 if (i == CIDX_swtch)
@@ -1055,8 +1022,12 @@ static void do_display(const struct termios *mode, int all)
1055 continue; 1022 continue;
1056 } 1023 }
1057#endif 1024#endif
1058 wrapf("%s = %s;", nth_string(control_name, i), 1025 ch = mode->c_cc[control_info[i].offset];
1059 visible(mode->c_cc[control_info[i].offset])); 1026 if (ch == _POSIX_VDISABLE)
1027 strcpy(G.buf, "<undef>");
1028 else
1029 visible(ch, G.buf, 0);
1030 wrapf("%s = %s;", nth_string(control_name, i), G.buf);
1060 } 1031 }
1061#if VEOF == VMIN 1032#if VEOF == VMIN
1062 if ((mode->c_lflag & ICANON) == 0) 1033 if ((mode->c_lflag & ICANON) == 0)
@@ -1072,7 +1043,7 @@ static void do_display(const struct termios *mode, int all)
1072 prev_type = mode_info[i].type; 1043 prev_type = mode_info[i].type;
1073 } 1044 }
1074 1045
1075 bitsp = mode_type_flag(mode_info[i].type, mode); 1046 bitsp = get_ptr_to_tcflag(mode_info[i].type, mode);
1076 mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits; 1047 mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits;
1077 if ((*bitsp & mask) == mode_info[i].bits) { 1048 if ((*bitsp & mask) == mode_info[i].bits) {
1078 if (all || (mode_info[i].flags & SANE_UNSET)) 1049 if (all || (mode_info[i].flags & SANE_UNSET))
@@ -1091,7 +1062,6 @@ static void do_display(const struct termios *mode, int all)
1091static void sane_mode(struct termios *mode) 1062static void sane_mode(struct termios *mode)
1092{ 1063{
1093 int i; 1064 int i;
1094 tcflag_t *bitsp;
1095 1065
1096 for (i = 0; i < NUM_control_info; ++i) { 1066 for (i = 0; i < NUM_control_info; ++i) {
1097#if VMIN == VEOF 1067#if VMIN == VEOF
@@ -1102,14 +1072,17 @@ static void sane_mode(struct termios *mode)
1102 } 1072 }
1103 1073
1104 for (i = 0; i < NUM_mode_info; ++i) { 1074 for (i = 0; i < NUM_mode_info; ++i) {
1075 tcflag_t val;
1076 tcflag_t *bitsp = get_ptr_to_tcflag(mode_info[i].type, mode);
1077
1078 if (!bitsp)
1079 continue;
1080 val = *bitsp & ~((unsigned long)mode_info[i].mask);
1105 if (mode_info[i].flags & SANE_SET) { 1081 if (mode_info[i].flags & SANE_SET) {
1106 bitsp = mode_type_flag(mode_info[i].type, mode); 1082 *bitsp = val | mode_info[i].bits;
1107 *bitsp = (*bitsp & ~((unsigned long)mode_info[i].mask)) 1083 } else
1108 | mode_info[i].bits; 1084 if (mode_info[i].flags & SANE_UNSET) {
1109 } else if (mode_info[i].flags & SANE_UNSET) { 1085 *bitsp = val & ~mode_info[i].bits;
1110 bitsp = mode_type_flag(mode_info[i].type, mode);
1111 *bitsp = *bitsp & ~((unsigned long)mode_info[i].mask)
1112 & ~mode_info[i].bits;
1113 } 1086 }
1114 } 1087 }
1115} 1088}
@@ -1119,17 +1092,18 @@ static void set_mode(const struct mode_info *info, int reversed,
1119{ 1092{
1120 tcflag_t *bitsp; 1093 tcflag_t *bitsp;
1121 1094
1122 bitsp = mode_type_flag(info->type, mode); 1095 bitsp = get_ptr_to_tcflag(info->type, mode);
1123 1096
1124 if (bitsp) { 1097 if (bitsp) {
1098 tcflag_t val = *bitsp & ~info->mask;
1125 if (reversed) 1099 if (reversed)
1126 *bitsp = *bitsp & ~info->mask & ~info->bits; 1100 *bitsp = val & ~info->bits;
1127 else 1101 else
1128 *bitsp = (*bitsp & ~info->mask) | info->bits; 1102 *bitsp = val | info->bits;
1129 return; 1103 return;
1130 } 1104 }
1131 1105
1132 /* Combination mode */ 1106 /* !bitsp - it's a "combination" mode */
1133 if (info == &mode_info[IDX_evenp] || info == &mode_info[IDX_parity]) { 1107 if (info == &mode_info[IDX_evenp] || info == &mode_info[IDX_parity]) {
1134 if (reversed) 1108 if (reversed)
1135 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; 1109 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8;
@@ -1534,7 +1508,12 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1534 perror_on_device_and_die("%s"); 1508 perror_on_device_and_die("%s");
1535 1509
1536 if (memcmp(&mode, &new_mode, sizeof(mode)) != 0) { 1510 if (memcmp(&mode, &new_mode, sizeof(mode)) != 0) {
1537#if CIBAUD 1511/*
1512 * I think the below chunk is not necessary on Linux.
1513 * If you are deleting it, also delete STTY_speed_was_set bit -
1514 * it is only ever checked here.
1515 */
1516#if 0 /* was "if CIBAUD" */
1538 /* SunOS 4.1.3 (at least) has the problem that after this sequence, 1517 /* SunOS 4.1.3 (at least) has the problem that after this sequence,
1539 tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2); 1518 tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2);
1540 sometimes (m1 != m2). The only difference is in the four bits 1519 sometimes (m1 != m2). The only difference is in the four bits
diff --git a/coreutils/tail.c b/coreutils/tail.c
index 19fd8f695..07c71ca4b 100644
--- a/coreutils/tail.c
+++ b/coreutils/tail.c
@@ -25,7 +25,6 @@
25 */ 25 */
26 26
27//kbuild:lib-$(CONFIG_TAIL) += tail.o 27//kbuild:lib-$(CONFIG_TAIL) += tail.o
28//kbuild:lib-$(CONFIG_TAIL) += head_tail.o
29 28
30//usage:#define tail_trivial_usage 29//usage:#define tail_trivial_usage
31//usage: "[OPTIONS] [FILE]..." 30//usage: "[OPTIONS] [FILE]..."
@@ -51,7 +50,6 @@
51//usage: "nameserver 10.0.0.1\n" 50//usage: "nameserver 10.0.0.1\n"
52 51
53#include "libbb.h" 52#include "libbb.h"
54#include "head_tail.h"
55 53
56struct globals { 54struct globals {
57 bool from_top; 55 bool from_top;
@@ -69,15 +67,6 @@ static void tail_xprint_header(const char *fmt, const char *filename)
69static ssize_t tail_read(int fd, char *buf, size_t count) 67static ssize_t tail_read(int fd, char *buf, size_t count)
70{ 68{
71 ssize_t r; 69 ssize_t r;
72 off_t current;
73 struct stat sbuf;
74
75 /* /proc files report zero st_size, don't lseek them. */
76 if (fstat(fd, &sbuf) == 0 && sbuf.st_size > 0) {
77 current = lseek(fd, 0, SEEK_CUR);
78 if (sbuf.st_size < current)
79 xlseek(fd, 0, SEEK_SET);
80 }
81 70
82 r = full_read(fd, buf, count); 71 r = full_read(fd, buf, count);
83 if (r < 0) { 72 if (r < 0) {
@@ -98,7 +87,7 @@ static unsigned eat_num(const char *p)
98 p++; 87 p++;
99 G.from_top = 1; 88 G.from_top = 1;
100 } 89 }
101 return xatou_sfx(p, head_tail_suffixes); 90 return xatou_sfx(p, bkm_suffixes);
102} 91}
103 92
104int tail_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 93int tail_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@@ -363,7 +352,19 @@ int tail_main(int argc, char **argv)
363 if (nfiles > header_threshhold) { 352 if (nfiles > header_threshhold) {
364 fmt = header_fmt_str; 353 fmt = header_fmt_str;
365 } 354 }
366 while ((nread = tail_read(fd, tailbuf, BUFSIZ)) > 0) { 355 for (;;) {
356 /* tail -f keeps following files even if they are truncated */
357 struct stat sbuf;
358 /* /proc files report zero st_size, don't lseek them */
359 if (fstat(fd, &sbuf) == 0 && sbuf.st_size > 0) {
360 off_t current = lseek(fd, 0, SEEK_CUR);
361 if (sbuf.st_size < current)
362 xlseek(fd, 0, SEEK_SET);
363 }
364
365 nread = tail_read(fd, tailbuf, BUFSIZ);
366 if (nread <= 0)
367 break;
367 if (fmt) { 368 if (fmt) {
368 tail_xprint_header(fmt, filename); 369 tail_xprint_header(fmt, filename);
369 fmt = NULL; 370 fmt = NULL;