aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2015-10-19 12:53:35 +0100
committerRon Yorston <rmy@pobox.com>2015-10-19 12:53:35 +0100
commit8afe8ee83a274925340473fa4d0a984bdcbee740 (patch)
treeb78ed448cb6a55ba7d0ef8141a9f68b55b8acf11 /coreutils
parentcaab029609633220c417dc0aaa9025fd4b7a169c (diff)
parent3d0805e9e7c45e6c0f9fb5e587d8b4a5a5f3c74c (diff)
downloadbusybox-w32-8afe8ee83a274925340473fa4d0a984bdcbee740.tar.gz
busybox-w32-8afe8ee83a274925340473fa4d0a984bdcbee740.tar.bz2
busybox-w32-8afe8ee83a274925340473fa4d0a984bdcbee740.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/chown.c8
-rw-r--r--coreutils/dd.c4
-rw-r--r--coreutils/du.c37
-rw-r--r--coreutils/od_bloaty.c230
4 files changed, 149 insertions, 130 deletions
diff --git a/coreutils/chown.c b/coreutils/chown.c
index 679c0d832..247aa3bf1 100644
--- a/coreutils/chown.c
+++ b/coreutils/chown.c
@@ -11,9 +11,9 @@
11/* http://www.opengroup.org/onlinepubs/007904975/utilities/chown.html */ 11/* http://www.opengroup.org/onlinepubs/007904975/utilities/chown.html */
12 12
13//usage:#define chown_trivial_usage 13//usage:#define chown_trivial_usage
14//usage: "[-Rh"IF_DESKTOP("LHPcvf")"]... OWNER[<.|:>[GROUP]] FILE..." 14//usage: "[-Rh"IF_DESKTOP("LHPcvf")"]... USER[:[GRP]] FILE..."
15//usage:#define chown_full_usage "\n\n" 15//usage:#define chown_full_usage "\n\n"
16//usage: "Change the owner and/or group of each FILE to OWNER and/or GROUP\n" 16//usage: "Change the owner and/or group of each FILE to USER and/or GRP\n"
17//usage: "\n -R Recurse" 17//usage: "\n -R Recurse"
18//usage: "\n -h Affect symlinks instead of symlink targets" 18//usage: "\n -h Affect symlinks instead of symlink targets"
19//usage: IF_DESKTOP( 19//usage: IF_DESKTOP(
@@ -112,10 +112,6 @@ int chown_main(int argc UNUSED_PARAM, char **argv)
112 int opt, flags; 112 int opt, flags;
113 struct param_t param; 113 struct param_t param;
114 114
115 /* Just -1 might not work: uid_t may be unsigned long */
116 param.ugid.uid = -1L;
117 param.ugid.gid = -1L;
118
119#if ENABLE_FEATURE_CHOWN_LONG_OPTIONS 115#if ENABLE_FEATURE_CHOWN_LONG_OPTIONS
120 applet_long_options = chown_longopts; 116 applet_long_options = chown_longopts;
121#endif 117#endif
diff --git a/coreutils/dd.c b/coreutils/dd.c
index 589547e77..ccb91f69d 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -327,7 +327,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
327 *arg = '\0'; 327 *arg = '\0';
328 n = index_in_strings(conv_words, val); 328 n = index_in_strings(conv_words, val);
329 if (n < 0) 329 if (n < 0)
330 bb_error_msg_and_die(bb_msg_invalid_arg, val, "conv"); 330 bb_error_msg_and_die(bb_msg_invalid_arg_to, val, "conv");
331 G.flags |= (1 << n); 331 G.flags |= (1 << n);
332 if (!arg) /* no ',' left, so this was the last specifier */ 332 if (!arg) /* no ',' left, so this was the last specifier */
333 break; 333 break;
@@ -369,7 +369,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
369 int n; 369 int n;
370 n = index_in_strings(status_words, val); 370 n = index_in_strings(status_words, val);
371 if (n < 0) 371 if (n < 0)
372 bb_error_msg_and_die(bb_msg_invalid_arg, val, "status"); 372 bb_error_msg_and_die(bb_msg_invalid_arg_to, val, "status");
373 G.flags |= FLAG_STATUS << n; 373 G.flags |= FLAG_STATUS << n;
374 /*continue;*/ 374 /*continue;*/
375 } 375 }
diff --git a/coreutils/du.c b/coreutils/du.c
index 9c6ff8800..1889c16bb 100644
--- a/coreutils/du.c
+++ b/coreutils/du.c
@@ -75,7 +75,7 @@ enum {
75 75
76struct globals { 76struct globals {
77#if ENABLE_FEATURE_HUMAN_READABLE 77#if ENABLE_FEATURE_HUMAN_READABLE
78 unsigned long disp_hr; 78 unsigned long disp_unit;
79#else 79#else
80 unsigned disp_k; 80 unsigned disp_k;
81#endif 81#endif
@@ -89,18 +89,27 @@ struct globals {
89#define INIT_G() do { } while (0) 89#define INIT_G() do { } while (0)
90 90
91 91
92/* FIXME? coreutils' du rounds sizes up:
93 * for example, 1025k file is shown as "2" by du -m.
94 * We round to nearest.
95 */
96static void print(unsigned long long size, const char *filename) 92static void print(unsigned long long size, const char *filename)
97{ 93{
98 /* TODO - May not want to defer error checking here. */ 94 /* TODO - May not want to defer error checking here. */
99#if ENABLE_FEATURE_HUMAN_READABLE 95#if ENABLE_FEATURE_HUMAN_READABLE
96# if ENABLE_DESKTOP
97 /* ~30 bytes of code for extra comtat:
98 * coreutils' du rounds sizes up:
99 * for example, 1025k file is shown as "2" by du -m.
100 * We round to nearest if human-readable [too hard to fix],
101 * else (fixed scale such as -m), we round up. To that end,
102 * add yet another half of the unit before displaying:
103 */
104 if (G.disp_unit)
105 size += (G.disp_unit-1) / (unsigned)(512 * 2);
106# endif
100 printf("%s\t%s\n", 107 printf("%s\t%s\n",
101 /* size x 512 / G.disp_hr, show one fractional, 108 /* size x 512 / G.disp_unit.
102 * use suffixes if G.disp_hr == 0 */ 109 * If G.disp_unit == 0, show one fractional
103 make_human_readable_str(size, 512, G.disp_hr), 110 * and use suffixes
111 */
112 make_human_readable_str(size, 512, G.disp_unit),
104 filename); 113 filename);
105#else 114#else
106 if (G.disp_k) { 115 if (G.disp_k) {
@@ -199,10 +208,10 @@ int du_main(int argc UNUSED_PARAM, char **argv)
199 INIT_G(); 208 INIT_G();
200 209
201#if ENABLE_FEATURE_HUMAN_READABLE 210#if ENABLE_FEATURE_HUMAN_READABLE
202 IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 1024;) 211 IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_unit = 1024;)
203 IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 512;) 212 IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_unit = 512;)
204 if (getenv("POSIXLY_CORRECT")) /* TODO - a new libbb function? */ 213 if (getenv("POSIXLY_CORRECT")) /* TODO - a new libbb function? */
205 G.disp_hr = 512; 214 G.disp_unit = 512;
206#else 215#else
207 IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 1;) 216 IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 1;)
208 /* IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 0;) - G is pre-zeroed */ 217 /* IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 0;) - G is pre-zeroed */
@@ -220,13 +229,13 @@ int du_main(int argc UNUSED_PARAM, char **argv)
220 opt = getopt32(argv, "aHkLsx" "d:" "lc" "hm", &G.max_print_depth); 229 opt = getopt32(argv, "aHkLsx" "d:" "lc" "hm", &G.max_print_depth);
221 argv += optind; 230 argv += optind;
222 if (opt & OPT_h_for_humans) { 231 if (opt & OPT_h_for_humans) {
223 G.disp_hr = 0; 232 G.disp_unit = 0;
224 } 233 }
225 if (opt & OPT_m_mbytes) { 234 if (opt & OPT_m_mbytes) {
226 G.disp_hr = 1024*1024; 235 G.disp_unit = 1024*1024;
227 } 236 }
228 if (opt & OPT_k_kbytes) { 237 if (opt & OPT_k_kbytes) {
229 G.disp_hr = 1024; 238 G.disp_unit = 1024;
230 } 239 }
231#else 240#else
232 opt_complementary = "H-L:L-H:s-d:d-s:d+"; 241 opt_complementary = "H-L:L-H:s-d:d-s:d+";
diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c
index 1e7c5bfa0..3e0423a3d 100644
--- a/coreutils/od_bloaty.c
+++ b/coreutils/od_bloaty.c
@@ -66,7 +66,7 @@ enum {
66 /* -S was -s and also had optional parameter */ \ 66 /* -S was -s and also had optional parameter */ \
67 /* but in coreutils 6.3 it was renamed and now has */ \ 67 /* but in coreutils 6.3 it was renamed and now has */ \
68 /* _mandatory_ parameter */ \ 68 /* _mandatory_ parameter */ \
69 &str_A, &str_N, &str_j, &lst_t, &str_S, &bytes_per_block) 69 &str_A, &str_N, &str_j, &lst_t, &str_S, &G.bytes_per_block)
70 70
71 71
72/* Check for 0x7f is a coreutils 6.3 addition */ 72/* Check for 0x7f is a coreutils 6.3 addition */
@@ -181,38 +181,52 @@ struct ERR_width_bytes_has_bad_size {
181 char ERR_width_bytes_has_bad_size[ARRAY_SIZE(width_bytes) == N_SIZE_SPECS ? 1 : -1]; 181 char ERR_width_bytes_has_bad_size[ARRAY_SIZE(width_bytes) == N_SIZE_SPECS ? 1 : -1];
182}; 182};
183 183
184static smallint exit_code; 184struct globals {
185 smallint exit_code;
185 186
186static unsigned string_min; 187 unsigned string_min;
187 188
188/* An array of specs describing how to format each input block. */ 189 /* An array of specs describing how to format each input block. */
189static size_t n_specs; 190 unsigned n_specs;
190static struct tspec *spec; 191 struct tspec *spec;
191 192
192/* Function that accepts an address and an optional following char, 193 /* Function that accepts an address and an optional following char,
193 and prints the address and char to stdout. */ 194 and prints the address and char to stdout. */
194static void (*format_address)(off_t, char); 195 void (*format_address)(off_t, char);
195/* The difference between the old-style pseudo starting address and 196
196 the number of bytes to skip. */ 197 /* The difference between the old-style pseudo starting address and
198 the number of bytes to skip. */
197#if ENABLE_LONG_OPTS 199#if ENABLE_LONG_OPTS
198static off_t pseudo_offset; 200 off_t pseudo_offset;
199#else 201# define G_pseudo_offset G.pseudo_offset
200enum { pseudo_offset = 0 };
201#endif 202#endif
202/* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all 203 /* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all
203 input is formatted. */ 204 input is formatted. */
204 205
205/* The number of input bytes formatted per output line. It must be 206 /* The number of input bytes formatted per output line. It must be
206 a multiple of the least common multiple of the sizes associated with 207 a multiple of the least common multiple of the sizes associated with
207 the specified output types. It should be as large as possible, but 208 the specified output types. It should be as large as possible, but
208 no larger than 16 -- unless specified with the -w option. */ 209 no larger than 16 -- unless specified with the -w option. */
209static unsigned bytes_per_block = 32; /* have to use unsigned, not size_t */ 210 unsigned bytes_per_block; /* have to use unsigned, not size_t */
210 211
211/* A NULL-terminated list of the file-arguments from the command line. */ 212 /* A NULL-terminated list of the file-arguments from the command line. */
212static const char *const *file_list; 213 const char *const *file_list;
214
215 /* The input stream associated with the current file. */
216 FILE *in_stream;
217
218 bool not_first;
219 bool prev_pair_equal;
220} FIX_ALIASING;
221#if !ENABLE_LONG_OPTS
222enum { G_pseudo_offset = 0 };
223#endif
224#define G (*(struct globals*)&bb_common_bufsiz1)
225#define INIT_G() do { \
226 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
227 G.bytes_per_block = 32; \
228} while (0)
213 229
214/* The input stream associated with the current file. */
215static FILE *in_stream;
216 230
217#define MAX_INTEGRAL_TYPE_SIZE sizeof(ulonglong_t) 231#define MAX_INTEGRAL_TYPE_SIZE sizeof(ulonglong_t)
218static const unsigned char integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1] ALIGN1 = { 232static const unsigned char integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1] ALIGN1 = {
@@ -483,17 +497,17 @@ static void
483open_next_file(void) 497open_next_file(void)
484{ 498{
485 while (1) { 499 while (1) {
486 if (!*file_list) 500 if (!*G.file_list)
487 return; 501 return;
488 in_stream = fopen_or_warn_stdin(*file_list++); 502 G.in_stream = fopen_or_warn_stdin(*G.file_list++);
489 if (in_stream) { 503 if (G.in_stream) {
490 break; 504 break;
491 } 505 }
492 exit_code = 1; 506 G.exit_code = 1;
493 } 507 }
494 508
495 if ((option_mask32 & (OPT_N|OPT_S)) == OPT_N) 509 if ((option_mask32 & (OPT_N|OPT_S)) == OPT_N)
496 setbuf(in_stream, NULL); 510 setbuf(G.in_stream, NULL);
497} 511}
498 512
499/* Test whether there have been errors on in_stream, and close it if 513/* Test whether there have been errors on in_stream, and close it if
@@ -506,16 +520,16 @@ open_next_file(void)
506static void 520static void
507check_and_close(void) 521check_and_close(void)
508{ 522{
509 if (in_stream) { 523 if (G.in_stream) {
510 if (ferror(in_stream)) { 524 if (ferror(G.in_stream)) {
511 bb_error_msg("%s: read error", (in_stream == stdin) 525 bb_error_msg("%s: read error", (G.in_stream == stdin)
512 ? bb_msg_standard_input 526 ? bb_msg_standard_input
513 : file_list[-1] 527 : G.file_list[-1]
514 ); 528 );
515 exit_code = 1; 529 G.exit_code = 1;
516 } 530 }
517 fclose_if_not_stdin(in_stream); 531 fclose_if_not_stdin(G.in_stream);
518 in_stream = NULL; 532 G.in_stream = NULL;
519 } 533 }
520 534
521 if (ferror(stdout)) { 535 if (ferror(stdout)) {
@@ -751,9 +765,9 @@ decode_format_string(const char *s)
751 765
752 assert(s != next); 766 assert(s != next);
753 s = next; 767 s = next;
754 spec = xrealloc_vector(spec, 4, n_specs); 768 G.spec = xrealloc_vector(G.spec, 4, G.n_specs);
755 memcpy(&spec[n_specs], &tspec, sizeof(spec[0])); 769 memcpy(&G.spec[G.n_specs], &tspec, sizeof(G.spec[0]));
756 n_specs++; 770 G.n_specs++;
757 } 771 }
758} 772}
759 773
@@ -770,7 +784,7 @@ skip(off_t n_skip)
770 if (n_skip == 0) 784 if (n_skip == 0)
771 return; 785 return;
772 786
773 while (in_stream) { /* !EOF */ 787 while (G.in_stream) { /* !EOF */
774 struct stat file_stats; 788 struct stat file_stats;
775 789
776 /* First try seeking. For large offsets, this extra work is 790 /* First try seeking. For large offsets, this extra work is
@@ -788,15 +802,15 @@ skip(off_t n_skip)
788 If the number of bytes left to skip is at least 802 If the number of bytes left to skip is at least
789 as large as the size of the current file, we can 803 as large as the size of the current file, we can
790 decrement n_skip and go on to the next file. */ 804 decrement n_skip and go on to the next file. */
791 if (fstat(fileno(in_stream), &file_stats) == 0 805 if (fstat(fileno(G.in_stream), &file_stats) == 0
792 && S_ISREG(file_stats.st_mode) && file_stats.st_size > 0 806 && S_ISREG(file_stats.st_mode) && file_stats.st_size > 0
793 ) { 807 ) {
794 if (file_stats.st_size < n_skip) { 808 if (file_stats.st_size < n_skip) {
795 n_skip -= file_stats.st_size; 809 n_skip -= file_stats.st_size;
796 /* take "check & close / open_next" route */ 810 /* take "check & close / open_next" route */
797 } else { 811 } else {
798 if (fseeko(in_stream, n_skip, SEEK_CUR) != 0) 812 if (fseeko(G.in_stream, n_skip, SEEK_CUR) != 0)
799 exit_code = 1; 813 G.exit_code = 1;
800 return; 814 return;
801 } 815 }
802 } else { 816 } else {
@@ -809,7 +823,7 @@ skip(off_t n_skip)
809 while (n_skip > 0) { 823 while (n_skip > 0) {
810 if (n_skip < n_bytes_to_read) 824 if (n_skip < n_bytes_to_read)
811 n_bytes_to_read = n_skip; 825 n_bytes_to_read = n_skip;
812 n_bytes_read = fread(buf, 1, n_bytes_to_read, in_stream); 826 n_bytes_read = fread(buf, 1, n_bytes_to_read, G.in_stream);
813 n_skip -= n_bytes_read; 827 n_skip -= n_bytes_read;
814 if (n_bytes_read != n_bytes_to_read) 828 if (n_bytes_read != n_bytes_to_read)
815 break; /* EOF on this file or error */ 829 break; /* EOF on this file or error */
@@ -862,7 +876,7 @@ static void
862format_address_label(off_t address, char c) 876format_address_label(off_t address, char c)
863{ 877{
864 format_address_std(address, ' '); 878 format_address_std(address, ' ');
865 format_address_paren(address + pseudo_offset, c); 879 format_address_paren(address + G_pseudo_offset, c);
866} 880}
867#endif 881#endif
868 882
@@ -893,36 +907,34 @@ static void
893write_block(off_t current_offset, size_t n_bytes, 907write_block(off_t current_offset, size_t n_bytes,
894 const char *prev_block, const char *curr_block) 908 const char *prev_block, const char *curr_block)
895{ 909{
896 static char first = 1; 910 unsigned i;
897 static char prev_pair_equal = 0;
898 size_t i;
899 911
900 if (!(option_mask32 & OPT_v) 912 if (!(option_mask32 & OPT_v)
901 && !first 913 && G.not_first
902 && n_bytes == bytes_per_block 914 && n_bytes == G.bytes_per_block
903 && memcmp(prev_block, curr_block, bytes_per_block) == 0 915 && memcmp(prev_block, curr_block, G.bytes_per_block) == 0
904 ) { 916 ) {
905 if (prev_pair_equal) { 917 if (G.prev_pair_equal) {
906 /* The two preceding blocks were equal, and the current 918 /* The two preceding blocks were equal, and the current
907 block is the same as the last one, so print nothing. */ 919 block is the same as the last one, so print nothing. */
908 } else { 920 } else {
909 puts("*"); 921 puts("*");
910 prev_pair_equal = 1; 922 G.prev_pair_equal = 1;
911 } 923 }
912 } else { 924 } else {
913 first = 0; 925 G.not_first = 1;
914 prev_pair_equal = 0; 926 G.prev_pair_equal = 0;
915 for (i = 0; i < n_specs; i++) { 927 for (i = 0; i < G.n_specs; i++) {
916 if (i == 0) 928 if (i == 0)
917 format_address(current_offset, '\0'); 929 G.format_address(current_offset, '\0');
918 else 930 else
919 printf("%*s", address_pad_len_char - '0', ""); 931 printf("%*s", address_pad_len_char - '0', "");
920 (*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string); 932 (*G.spec[i].print_function) (n_bytes, curr_block, G.spec[i].fmt_string);
921 if (spec[i].hexl_mode_trailer) { 933 if (G.spec[i].hexl_mode_trailer) {
922 /* space-pad out to full line width, then dump the trailer */ 934 /* space-pad out to full line width, then dump the trailer */
923 unsigned datum_width = width_bytes[spec[i].size]; 935 unsigned datum_width = width_bytes[G.spec[i].size];
924 unsigned blank_fields = (bytes_per_block - n_bytes) / datum_width; 936 unsigned blank_fields = (G.bytes_per_block - n_bytes) / datum_width;
925 unsigned field_width = spec[i].field_width + 1; 937 unsigned field_width = G.spec[i].field_width + 1;
926 printf("%*s", blank_fields * field_width, ""); 938 printf("%*s", blank_fields * field_width, "");
927 dump_hexl_mode_trailer(n_bytes, curr_block); 939 dump_hexl_mode_trailer(n_bytes, curr_block);
928 } 940 }
@@ -934,19 +946,19 @@ write_block(off_t current_offset, size_t n_bytes,
934static void 946static void
935read_block(size_t n, char *block, size_t *n_bytes_in_buffer) 947read_block(size_t n, char *block, size_t *n_bytes_in_buffer)
936{ 948{
937 assert(0 < n && n <= bytes_per_block); 949 assert(0 < n && n <= G.bytes_per_block);
938 950
939 *n_bytes_in_buffer = 0; 951 *n_bytes_in_buffer = 0;
940 952
941 if (n == 0) 953 if (n == 0)
942 return; 954 return;
943 955
944 while (in_stream != NULL) { /* EOF. */ 956 while (G.in_stream != NULL) { /* EOF. */
945 size_t n_needed; 957 size_t n_needed;
946 size_t n_read; 958 size_t n_read;
947 959
948 n_needed = n - *n_bytes_in_buffer; 960 n_needed = n - *n_bytes_in_buffer;
949 n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, in_stream); 961 n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, G.in_stream);
950 *n_bytes_in_buffer += n_read; 962 *n_bytes_in_buffer += n_read;
951 if (n_read == n_needed) 963 if (n_read == n_needed)
952 break; 964 break;
@@ -965,8 +977,8 @@ get_lcm(void)
965 size_t i; 977 size_t i;
966 int l_c_m = 1; 978 int l_c_m = 1;
967 979
968 for (i = 0; i < n_specs; i++) 980 for (i = 0; i < G.n_specs; i++)
969 l_c_m = lcm(l_c_m, width_bytes[(int) spec[i].size]); 981 l_c_m = lcm(l_c_m, width_bytes[(int) G.spec[i].size]);
970 return l_c_m; 982 return l_c_m;
971} 983}
972 984
@@ -987,8 +999,8 @@ dump(off_t current_offset, off_t end_offset)
987 int idx; 999 int idx;
988 size_t n_bytes_read; 1000 size_t n_bytes_read;
989 1001
990 block[0] = xmalloc(2 * bytes_per_block); 1002 block[0] = xmalloc(2 * G.bytes_per_block);
991 block[1] = block[0] + bytes_per_block; 1003 block[1] = block[0] + G.bytes_per_block;
992 1004
993 idx = 0; 1005 idx = 0;
994 if (option_mask32 & OPT_N) { 1006 if (option_mask32 & OPT_N) {
@@ -998,21 +1010,21 @@ dump(off_t current_offset, off_t end_offset)
998 n_bytes_read = 0; 1010 n_bytes_read = 0;
999 break; 1011 break;
1000 } 1012 }
1001 n_needed = MIN(end_offset - current_offset, (off_t) bytes_per_block); 1013 n_needed = MIN(end_offset - current_offset, (off_t) G.bytes_per_block);
1002 read_block(n_needed, block[idx], &n_bytes_read); 1014 read_block(n_needed, block[idx], &n_bytes_read);
1003 if (n_bytes_read < bytes_per_block) 1015 if (n_bytes_read < G.bytes_per_block)
1004 break; 1016 break;
1005 assert(n_bytes_read == bytes_per_block); 1017 assert(n_bytes_read == G.bytes_per_block);
1006 write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]); 1018 write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
1007 current_offset += n_bytes_read; 1019 current_offset += n_bytes_read;
1008 idx ^= 1; 1020 idx ^= 1;
1009 } 1021 }
1010 } else { 1022 } else {
1011 while (1) { 1023 while (1) {
1012 read_block(bytes_per_block, block[idx], &n_bytes_read); 1024 read_block(G.bytes_per_block, block[idx], &n_bytes_read);
1013 if (n_bytes_read < bytes_per_block) 1025 if (n_bytes_read < G.bytes_per_block)
1014 break; 1026 break;
1015 assert(n_bytes_read == bytes_per_block); 1027 assert(n_bytes_read == G.bytes_per_block);
1016 write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]); 1028 write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]);
1017 current_offset += n_bytes_read; 1029 current_offset += n_bytes_read;
1018 idx ^= 1; 1030 idx ^= 1;
@@ -1035,7 +1047,7 @@ dump(off_t current_offset, off_t end_offset)
1035 current_offset += n_bytes_read; 1047 current_offset += n_bytes_read;
1036 } 1048 }
1037 1049
1038 format_address(current_offset, '\n'); 1050 G.format_address(current_offset, '\n');
1039 1051
1040 if ((option_mask32 & OPT_N) && current_offset >= end_offset) 1052 if ((option_mask32 & OPT_N) && current_offset >= end_offset)
1041 check_and_close(); 1053 check_and_close();
@@ -1066,16 +1078,16 @@ dump(off_t current_offset, off_t end_offset)
1066static void 1078static void
1067dump_strings(off_t address, off_t end_offset) 1079dump_strings(off_t address, off_t end_offset)
1068{ 1080{
1069 unsigned bufsize = MAX(100, string_min); 1081 unsigned bufsize = MAX(100, G.string_min);
1070 unsigned char *buf = xmalloc(bufsize); 1082 unsigned char *buf = xmalloc(bufsize);
1071 1083
1072 while (1) { 1084 while (1) {
1073 size_t i; 1085 size_t i;
1074 int c; 1086 int c;
1075 1087
1076 /* See if the next 'string_min' chars are all printing chars. */ 1088 /* See if the next 'G.string_min' chars are all printing chars. */
1077 tryline: 1089 tryline:
1078 if ((option_mask32 & OPT_N) && (end_offset - string_min <= address)) 1090 if ((option_mask32 & OPT_N) && (end_offset - G.string_min <= address))
1079 break; 1091 break;
1080 i = 0; 1092 i = 0;
1081 while (!(option_mask32 & OPT_N) || address < end_offset) { 1093 while (!(option_mask32 & OPT_N) || address < end_offset) {
@@ -1084,8 +1096,8 @@ dump_strings(off_t address, off_t end_offset)
1084 buf = xrealloc(buf, bufsize); 1096 buf = xrealloc(buf, bufsize);
1085 } 1097 }
1086 1098
1087 while (in_stream) { /* !EOF */ 1099 while (G.in_stream) { /* !EOF */
1088 c = fgetc(in_stream); 1100 c = fgetc(G.in_stream);
1089 if (c != EOF) 1101 if (c != EOF)
1090 goto got_char; 1102 goto got_char;
1091 check_and_close(); 1103 check_and_close();
@@ -1102,12 +1114,12 @@ dump_strings(off_t address, off_t end_offset)
1102 buf[i++] = c; /* String continues; store it all. */ 1114 buf[i++] = c; /* String continues; store it all. */
1103 } 1115 }
1104 1116
1105 if (i < string_min) /* Too short! */ 1117 if (i < G.string_min) /* Too short! */
1106 goto tryline; 1118 goto tryline;
1107 1119
1108 /* If we get here, the string is all printable and NUL-terminated */ 1120 /* If we get here, the string is all printable and NUL-terminated */
1109 buf[i] = 0; 1121 buf[i] = 0;
1110 format_address(address - i - 1, ' '); 1122 G.format_address(address - i - 1, ' ');
1111 1123
1112 for (i = 0; (c = buf[i]); i++) { 1124 for (i = 0; (c = buf[i]); i++) {
1113 switch (c) { 1125 switch (c) {
@@ -1125,7 +1137,7 @@ dump_strings(off_t address, off_t end_offset)
1125 } 1137 }
1126 1138
1127 /* We reach this point only if we search through 1139 /* We reach this point only if we search through
1128 (max_bytes_to_format - string_min) bytes before reaching EOF. */ 1140 (max_bytes_to_format - G.string_min) bytes before reaching EOF. */
1129 check_and_close(); 1141 check_and_close();
1130 ret: 1142 ret:
1131 free(buf); 1143 free(buf);
@@ -1197,8 +1209,10 @@ int od_main(int argc UNUSED_PARAM, char **argv)
1197 /* The maximum number of bytes that will be formatted. */ 1209 /* The maximum number of bytes that will be formatted. */
1198 off_t max_bytes_to_format = 0; 1210 off_t max_bytes_to_format = 0;
1199 1211
1200 spec = NULL; 1212 INIT_G();
1201 format_address = format_address_std; 1213
1214 /*G.spec = NULL; - already is */
1215 G.format_address = format_address_std;
1202 address_base_char = 'o'; 1216 address_base_char = 'o';
1203 address_pad_len_char = '7'; 1217 address_pad_len_char = '7';
1204 1218
@@ -1224,7 +1238,7 @@ int od_main(int argc UNUSED_PARAM, char **argv)
1224 bb_error_msg_and_die("bad output address radix " 1238 bb_error_msg_and_die("bad output address radix "
1225 "'%c' (must be [doxn])", str_A[0]); 1239 "'%c' (must be [doxn])", str_A[0]);
1226 pos = p - doxn; 1240 pos = p - doxn;
1227 if (pos == 3) format_address = format_address_none; 1241 if (pos == 3) G.format_address = format_address_none;
1228 address_base_char = doxn_address_base_char[pos]; 1242 address_base_char = doxn_address_base_char[pos];
1229 address_pad_len_char = doxn_address_pad_len_char[pos]; 1243 address_pad_len_char = doxn_address_pad_len_char[pos];
1230 } 1244 }
@@ -1247,11 +1261,11 @@ int od_main(int argc UNUSED_PARAM, char **argv)
1247 if (opt & OPT_x) decode_format_string("x2"); 1261 if (opt & OPT_x) decode_format_string("x2");
1248 if (opt & OPT_s) decode_format_string("d2"); 1262 if (opt & OPT_s) decode_format_string("d2");
1249 if (opt & OPT_S) { 1263 if (opt & OPT_S) {
1250 string_min = xstrtou_sfx(str_S, 0, bkm_suffixes); 1264 G.string_min = xstrtou_sfx(str_S, 0, bkm_suffixes);
1251 } 1265 }
1252 1266
1253 // Bloat: 1267 // Bloat:
1254 //if ((option_mask32 & OPT_S) && n_specs > 0) 1268 //if ((option_mask32 & OPT_S) && G.n_specs > 0)
1255 // bb_error_msg_and_die("no type may be specified when dumping strings"); 1269 // bb_error_msg_and_die("no type may be specified when dumping strings");
1256 1270
1257 /* If the --traditional option is used, there may be from 1271 /* If the --traditional option is used, there may be from
@@ -1307,14 +1321,14 @@ int od_main(int argc UNUSED_PARAM, char **argv)
1307 } 1321 }
1308 1322
1309 if (pseudo_start >= 0) { 1323 if (pseudo_start >= 0) {
1310 if (format_address == format_address_none) { 1324 if (G.format_address == format_address_none) {
1311 address_base_char = 'o'; 1325 address_base_char = 'o';
1312 address_pad_len_char = '7'; 1326 address_pad_len_char = '7';
1313 format_address = format_address_paren; 1327 G.format_address = format_address_paren;
1314 } else { 1328 } else {
1315 format_address = format_address_label; 1329 G.format_address = format_address_label;
1316 } 1330 }
1317 pseudo_offset = pseudo_start - n_bytes_to_skip; 1331 G_pseudo_offset = pseudo_start - n_bytes_to_skip;
1318 } 1332 }
1319 } 1333 }
1320 /* else: od --traditional (without args) */ 1334 /* else: od --traditional (without args) */
@@ -1327,45 +1341,45 @@ int od_main(int argc UNUSED_PARAM, char **argv)
1327 bb_error_msg_and_die("SKIP + SIZE is too large"); 1341 bb_error_msg_and_die("SKIP + SIZE is too large");
1328 } 1342 }
1329 1343
1330 if (n_specs == 0) { 1344 if (G.n_specs == 0) {
1331 decode_format_string("o2"); 1345 decode_format_string("o2");
1332 /*n_specs = 1; - done by decode_format_string */ 1346 /*G.n_specs = 1; - done by decode_format_string */
1333 } 1347 }
1334 1348
1335 /* If no files were listed on the command line, 1349 /* If no files were listed on the command line,
1336 set the global pointer FILE_LIST so that it 1350 set the global pointer FILE_LIST so that it
1337 references the null-terminated list of one name: "-". */ 1351 references the null-terminated list of one name: "-". */
1338 file_list = bb_argv_dash; 1352 G.file_list = bb_argv_dash;
1339 if (argv[0]) { 1353 if (argv[0]) {
1340 /* Set the global pointer FILE_LIST so that it 1354 /* Set the global pointer FILE_LIST so that it
1341 references the first file-argument on the command-line. */ 1355 references the first file-argument on the command-line. */
1342 file_list = (char const *const *) argv; 1356 G.file_list = (char const *const *) argv;
1343 } 1357 }
1344 1358
1345 /* Open the first input file */ 1359 /* Open the first input file */
1346 open_next_file(); 1360 open_next_file();
1347 /* Skip over any unwanted header bytes */ 1361 /* Skip over any unwanted header bytes */
1348 skip(n_bytes_to_skip); 1362 skip(n_bytes_to_skip);
1349 if (!in_stream) 1363 if (!G.in_stream)
1350 return EXIT_FAILURE; 1364 return EXIT_FAILURE;
1351 1365
1352 /* Compute output block length */ 1366 /* Compute output block length */
1353 l_c_m = get_lcm(); 1367 l_c_m = get_lcm();
1354 1368
1355 if (opt & OPT_w) { /* -w: width */ 1369 if (opt & OPT_w) { /* -w: width */
1356 if (!bytes_per_block || bytes_per_block % l_c_m != 0) { 1370 if (!G.bytes_per_block || G.bytes_per_block % l_c_m != 0) {
1357 bb_error_msg("warning: invalid width %u; using %d instead", 1371 bb_error_msg("warning: invalid width %u; using %d instead",
1358 (unsigned)bytes_per_block, l_c_m); 1372 (unsigned)G.bytes_per_block, l_c_m);
1359 bytes_per_block = l_c_m; 1373 G.bytes_per_block = l_c_m;
1360 } 1374 }
1361 } else { 1375 } else {
1362 bytes_per_block = l_c_m; 1376 G.bytes_per_block = l_c_m;
1363 if (l_c_m < DEFAULT_BYTES_PER_BLOCK) 1377 if (l_c_m < DEFAULT_BYTES_PER_BLOCK)
1364 bytes_per_block *= DEFAULT_BYTES_PER_BLOCK / l_c_m; 1378 G.bytes_per_block *= DEFAULT_BYTES_PER_BLOCK / l_c_m;
1365 } 1379 }
1366 1380
1367#ifdef DEBUG 1381#ifdef DEBUG
1368 for (i = 0; i < n_specs; i++) { 1382 for (i = 0; i < G.n_specs; i++) {
1369 printf("%d: fmt=\"%s\" width=%d\n", 1383 printf("%d: fmt=\"%s\" width=%d\n",
1370 i, spec[i].fmt_string, width_bytes[spec[i].size]); 1384 i, spec[i].fmt_string, width_bytes[spec[i].size]);
1371 } 1385 }
@@ -1379,5 +1393,5 @@ int od_main(int argc UNUSED_PARAM, char **argv)
1379 if (fclose(stdin)) 1393 if (fclose(stdin))
1380 bb_perror_msg_and_die(bb_msg_standard_input); 1394 bb_perror_msg_and_die(bb_msg_standard_input);
1381 1395
1382 return exit_code; 1396 return G.exit_code;
1383} 1397}