aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/Config.src2
-rw-r--r--coreutils/chroot.c8
-rw-r--r--coreutils/cksum.c1
-rw-r--r--coreutils/date.c3
-rw-r--r--coreutils/dd.c6
-rw-r--r--coreutils/ln.c6
-rw-r--r--coreutils/ls.c73
-rw-r--r--coreutils/printenv.c11
-rw-r--r--coreutils/split.c4
-rw-r--r--coreutils/test.c2
-rw-r--r--coreutils/tr.c6
11 files changed, 73 insertions, 49 deletions
diff --git a/coreutils/Config.src b/coreutils/Config.src
index 6297f43a3..2769aa07d 100644
--- a/coreutils/Config.src
+++ b/coreutils/Config.src
@@ -594,7 +594,7 @@ config FEATURE_SPLIT_FANCY
594config STAT 594config STAT
595 bool "stat" 595 bool "stat"
596 default y 596 default y
597 depends on PLATFORM_LINUX # statfs() 597 select PLATFORM_LINUX # statfs()
598 help 598 help
599 display file or filesystem status. 599 display file or filesystem status.
600 600
diff --git a/coreutils/chroot.c b/coreutils/chroot.c
index b80a12ee0..5ac2e890e 100644
--- a/coreutils/chroot.c
+++ b/coreutils/chroot.c
@@ -23,11 +23,9 @@ int chroot_main(int argc UNUSED_PARAM, char **argv)
23 ++argv; 23 ++argv;
24 if (!*argv) { /* no 2nd param (PROG), use shell */ 24 if (!*argv) { /* no 2nd param (PROG), use shell */
25 argv -= 2; 25 argv -= 2;
26 argv[0] = getenv("SHELL"); 26 argv[0] = (char *) get_shell_name();
27 if (!argv[0]) { 27 argv[1] = (char *) "-i"; /* GNU coreutils 8.4 compat */
28 argv[0] = (char *) DEFAULT_SHELL; 28 /*argv[2] = NULL; - already is */
29 }
30 argv[1] = (char *) "-i";
31 } 29 }
32 30
33 BB_EXECVP_or_die(argv); 31 BB_EXECVP_or_die(argv);
diff --git a/coreutils/cksum.c b/coreutils/cksum.c
index 7a37e6add..53fb87a78 100644
--- a/coreutils/cksum.c
+++ b/coreutils/cksum.c
@@ -38,6 +38,7 @@ int cksum_main(int argc UNUSED_PARAM, char **argv)
38 38
39#define read_buf bb_common_bufsiz1 39#define read_buf bb_common_bufsiz1
40 while ((bytes_read = safe_read(fd, read_buf, sizeof(read_buf))) > 0) { 40 while ((bytes_read = safe_read(fd, read_buf, sizeof(read_buf))) > 0) {
41 length += bytes_read;
41 crc = crc32_block_endian1(crc, read_buf, bytes_read, crc32_table); 42 crc = crc32_block_endian1(crc, read_buf, bytes_read, crc32_table);
42 } 43 }
43 close(fd); 44 close(fd);
diff --git a/coreutils/date.c b/coreutils/date.c
index d36ed83fd..497031991 100644
--- a/coreutils/date.c
+++ b/coreutils/date.c
@@ -42,7 +42,8 @@
42//config:config FEATURE_DATE_NANO 42//config:config FEATURE_DATE_NANO
43//config: bool "Support %[num]N nanosecond format specifier" 43//config: bool "Support %[num]N nanosecond format specifier"
44//config: default n 44//config: default n
45//config: depends on DATE && PLATFORM_LINUX # syscall(__NR_clock_gettime) 45//config: depends on DATE # syscall(__NR_clock_gettime)
46//config: select PLATFORM_LINUX
46//config: help 47//config: help
47//config: Support %[num]N format specifier. Adds ~250 bytes of code. 48//config: Support %[num]N format specifier. Adds ~250 bytes of code.
48//config: 49//config:
diff --git a/coreutils/dd.c b/coreutils/dd.c
index da205ec69..544ece051 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -409,5 +409,11 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
409 out_status: 409 out_status:
410 dd_output_status(0); 410 dd_output_status(0);
411 411
412 if (ENABLE_FEATURE_CLEAN_UP) {
413 free(obuf);
414 if (flags & FLAG_TWOBUFS)
415 free(ibuf);
416 }
417
412 return exitcode; 418 return exitcode;
413} 419}
diff --git a/coreutils/ln.c b/coreutils/ln.c
index ddad120d1..6da290c11 100644
--- a/coreutils/ln.c
+++ b/coreutils/ln.c
@@ -40,8 +40,12 @@ int ln_main(int argc, char **argv)
40 last = argv[argc - 1]; 40 last = argv[argc - 1];
41 argv += optind; 41 argv += optind;
42 42
43 if (argc == optind + 1) { 43 if (!argv[1]) {
44 /* "ln PATH/TO/FILE" -> "ln PATH/TO/FILE FILE" */
44 *--argv = last; 45 *--argv = last;
46 /* xstrdup is needed: "ln -s PATH/TO/FILE/" is equivalent to
47 * "ln -s PATH/TO/FILE/ FILE", not "ln -s PATH/TO/FILE FILE"
48 */
45 last = bb_get_last_path_component_strip(xstrdup(last)); 49 last = bb_get_last_path_component_strip(xstrdup(last));
46 } 50 }
47 51
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 1afe28c8d..4a41db76a 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -1,6 +1,5 @@
1/* vi: set sw=4 ts=4: */ 1/* vi: set sw=4 ts=4: */
2/* 2/*
3 * tiny-ls.c version 0.1.0: A minimalist 'ls'
4 * Copyright (C) 1996 Brian Candler <B.Candler@pobox.com> 3 * Copyright (C) 1996 Brian Candler <B.Candler@pobox.com>
5 * 4 *
6 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 5 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
@@ -159,7 +158,7 @@ STYLE_MASK = STYLE_SINGLE,
159 158
160/* which of the three times will be used */ 159/* which of the three times will be used */
161TIME_CHANGE = (1 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS, 160TIME_CHANGE = (1 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS,
162TIME_ACCESS = (1 << 22) * ENABLE_FEATURE_LS_TIMESTAMPS, 161TIME_ACCESS = (2 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS,
163TIME_MASK = (3 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS, 162TIME_MASK = (3 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS,
164 163
165/* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */ 164/* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */
@@ -189,10 +188,11 @@ LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \
189/* Not fully compatible - we show not only '/' but other chars too */ 188/* Not fully compatible - we show not only '/' but other chars too */
190/* -SXvhTw GNU options, busybox optionally supports */ 189/* -SXvhTw GNU options, busybox optionally supports */
191/* -T TABWIDTH is ignored (we don't use tabs on output) */ 190/* -T TABWIDTH is ignored (we don't use tabs on output) */
192/* -K SELinux mandated options, busybox optionally supports */ 191/* -KZ SELinux mandated options, busybox optionally supports */
192/* (coreutils 8.4 has no -K, remove it?) */
193/* -e I think we made this one up (looks similar to GNU --full-time) */ 193/* -e I think we made this one up (looks similar to GNU --full-time) */
194/* Std opts we do not support: */ 194/* We already used up all 32 bits, if we need to add more, candidates for removal: */
195/* -H Follow the links on command line only */ 195/* -K, -T, -e (add --full-time instead) */
196static const char ls_options[] ALIGN1 = 196static const char ls_options[] ALIGN1 =
197 "Cadil1gnsxQAk" /* 13 opts, total 13 */ 197 "Cadil1gnsxQAk" /* 13 opts, total 13 */
198 IF_FEATURE_LS_TIMESTAMPS("cetu") /* 4, 17 */ 198 IF_FEATURE_LS_TIMESTAMPS("cetu") /* 4, 17 */
@@ -203,7 +203,7 @@ static const char ls_options[] ALIGN1 =
203 IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 28 */ 203 IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 28 */
204 IF_FEATURE_HUMAN_READABLE("h") /* 1, 29 */ 204 IF_FEATURE_HUMAN_READABLE("h") /* 1, 29 */
205 IF_FEATURE_AUTOWIDTH("T:w:") /* 2, 31 */ 205 IF_FEATURE_AUTOWIDTH("T:w:") /* 2, 31 */
206 ; 206 /* with --color, we use all 32 bits */;
207enum { 207enum {
208 //OPT_C = (1 << 0), 208 //OPT_C = (1 << 0),
209 //OPT_a = (1 << 1), 209 //OPT_a = (1 << 1),
@@ -234,8 +234,8 @@ enum {
234 OPTBIT_Z, /* 25 */ 234 OPTBIT_Z, /* 25 */
235 OPTBIT_L = OPTBIT_K + 2 * ENABLE_SELINUX, 235 OPTBIT_L = OPTBIT_K + 2 * ENABLE_SELINUX,
236 OPTBIT_H, /* 27 */ 236 OPTBIT_H, /* 27 */
237 OPTBIT_h = OPTBIT_L + 1 * ENABLE_FEATURE_LS_FOLLOWLINKS, 237 OPTBIT_h = OPTBIT_L + 2 * ENABLE_FEATURE_LS_FOLLOWLINKS,
238 OPTBIT_T = OPTBIT_h + 2 * ENABLE_FEATURE_HUMAN_READABLE, 238 OPTBIT_T = OPTBIT_h + 1 * ENABLE_FEATURE_HUMAN_READABLE,
239 OPTBIT_w, /* 30 */ 239 OPTBIT_w, /* 30 */
240 OPTBIT_color = OPTBIT_T + 2 * ENABLE_FEATURE_AUTOWIDTH, 240 OPTBIT_color = OPTBIT_T + 2 * ENABLE_FEATURE_AUTOWIDTH,
241 241
@@ -268,13 +268,13 @@ static const uint32_t opt_flags[] = {
268 LIST_INO, /* i */ 268 LIST_INO, /* i */
269 LIST_LONG | STYLE_LONG, /* l */ 269 LIST_LONG | STYLE_LONG, /* l */
270 STYLE_SINGLE, /* 1 */ 270 STYLE_SINGLE, /* 1 */
271 0, /* g (don't show owner) - handled via OPT_g */ 271 LIST_LONG | STYLE_LONG, /* g (don't show owner) - handled via OPT_g. assumes l */
272 LIST_ID_NUMERIC, /* n */ 272 LIST_ID_NUMERIC | LIST_LONG | STYLE_LONG, /* n (assumes l) */
273 LIST_BLOCKS, /* s */ 273 LIST_BLOCKS, /* s */
274 DISP_ROWS | STYLE_COLUMNAR, /* x */ 274 DISP_ROWS | STYLE_COLUMNAR, /* x */
275 0, /* Q (quote filename) - handled via OPT_Q */ 275 0, /* Q (quote filename) - handled via OPT_Q */
276 DISP_HIDDEN, /* A */ 276 DISP_HIDDEN, /* A */
277 ENABLE_SELINUX * LIST_CONTEXT, /* k (ignored if !SELINUX) */ 277 ENABLE_SELINUX * (LIST_CONTEXT|STYLE_SINGLE), /* k (ignored if !SELINUX) */
278#if ENABLE_FEATURE_LS_TIMESTAMPS 278#if ENABLE_FEATURE_LS_TIMESTAMPS
279 TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */ 279 TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */
280 LIST_FULLTIME, /* e */ 280 LIST_FULLTIME, /* e */
@@ -295,8 +295,8 @@ static const uint32_t opt_flags[] = {
295 DISP_RECURSIVE, /* R */ 295 DISP_RECURSIVE, /* R */
296#endif 296#endif
297#if ENABLE_SELINUX 297#if ENABLE_SELINUX
298 LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME, /* K */ 298 LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME|STYLE_SINGLE, /* K */
299 LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT, /* Z */ 299 LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT|STYLE_SINGLE, /* Z */
300#endif 300#endif
301 (1U << 31) 301 (1U << 31)
302 /* options after Z are not processed through opt_flags */ 302 /* options after Z are not processed through opt_flags */
@@ -682,19 +682,28 @@ static NOINLINE unsigned list_single(const struct dnode *dn)
682 682
683 if (all_fmt & LIST_INO) 683 if (all_fmt & LIST_INO)
684 column += printf("%7llu ", (long long) dn->dstat.st_ino); 684 column += printf("%7llu ", (long long) dn->dstat.st_ino);
685//TODO: -h should affect -s too:
685 if (all_fmt & LIST_BLOCKS) 686 if (all_fmt & LIST_BLOCKS)
686#if ENABLE_PLATFORM_MINGW32 687#if ENABLE_PLATFORM_MINGW32
687 /* MinGW does not have st_blocks */ 688 /* MinGW does not have st_blocks */
688 column += printf("%4"OFF_FMT"u ", (off_t)0); 689 column += printf("%6"OFF_FMT"u ", (off_t)0);
689#else 690#else
690 column += printf("%4"OFF_FMT"u ", (off_t) (dn->dstat.st_blocks >> 1)); 691 column += printf("%6"OFF_FMT"u ", (off_t) (dn->dstat.st_blocks >> 1));
691#endif 692#endif
692 if (all_fmt & LIST_MODEBITS) 693 if (all_fmt & LIST_MODEBITS)
693 column += printf("%-10s ", (char *) bb_mode_string(dn->dstat.st_mode)); 694 column += printf("%-10s ", (char *) bb_mode_string(dn->dstat.st_mode));
694 if (all_fmt & LIST_NLINKS) 695 if (all_fmt & LIST_NLINKS)
695 column += printf("%4lu ", (long) dn->dstat.st_nlink); 696 column += printf("%4lu ", (long) dn->dstat.st_nlink);
697 if (all_fmt & LIST_ID_NUMERIC) {
698 if (option_mask32 & OPT_g)
699 column += printf("%-8u ", (int) dn->dstat.st_gid);
700 else
701 column += printf("%-8u %-8u ",
702 (int) dn->dstat.st_uid,
703 (int) dn->dstat.st_gid);
704 }
696#if ENABLE_FEATURE_LS_USERNAME 705#if ENABLE_FEATURE_LS_USERNAME
697 if (all_fmt & LIST_ID_NAME) { 706 else if (all_fmt & LIST_ID_NAME) {
698 if (option_mask32 & OPT_g) { 707 if (option_mask32 & OPT_g) {
699 column += printf("%-8.8s ", 708 column += printf("%-8.8s ",
700 get_cached_groupname(dn->dstat.st_gid)); 709 get_cached_groupname(dn->dstat.st_gid));
@@ -705,14 +714,6 @@ static NOINLINE unsigned list_single(const struct dnode *dn)
705 } 714 }
706 } 715 }
707#endif 716#endif
708 if (all_fmt & LIST_ID_NUMERIC) {
709 if (option_mask32 & OPT_g)
710 column += printf("%-8u ", (int) dn->dstat.st_gid);
711 else
712 column += printf("%-8u %-8u ",
713 (int) dn->dstat.st_uid,
714 (int) dn->dstat.st_gid);
715 }
716 if (all_fmt & LIST_SIZE) { 717 if (all_fmt & LIST_SIZE) {
717 if (S_ISBLK(dn->dstat.st_mode) || S_ISCHR(dn->dstat.st_mode)) { 718 if (S_ISBLK(dn->dstat.st_mode) || S_ISCHR(dn->dstat.st_mode)) {
718 column += printf("%4u, %3u ", 719 column += printf("%4u, %3u ",
@@ -739,9 +740,12 @@ static NOINLINE unsigned list_single(const struct dnode *dn)
739 ttime = dn->dstat.st_ctime; 740 ttime = dn->dstat.st_ctime;
740 filetime = ctime(&ttime); 741 filetime = ctime(&ttime);
741 /* filetime's format: "Wed Jun 30 21:49:08 1993\n" */ 742 /* filetime's format: "Wed Jun 30 21:49:08 1993\n" */
742 if (all_fmt & LIST_FULLTIME) 743 if (all_fmt & LIST_FULLTIME) { /* -e */
744 /* Note: coreutils 8.4 ls --full-time prints:
745 * 2009-07-13 17:49:27.000000000 +0200
746 */
743 column += printf("%.24s ", filetime); 747 column += printf("%.24s ", filetime);
744 else { /* LIST_DATE_TIME */ 748 } else { /* LIST_DATE_TIME */
745 /* current_time_t ~== time(NULL) */ 749 /* current_time_t ~== time(NULL) */
746 time_t age = current_time_t - ttime; 750 time_t age = current_time_t - ttime;
747 printf("%.6s ", filetime + 4); /* "Jun 30" */ 751 printf("%.6s ", filetime + 4); /* "Jun 30" */
@@ -1049,7 +1053,8 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
1049 1053
1050 init_unicode(); 1054 init_unicode();
1051 1055
1052 all_fmt = ENABLE_FEATURE_LS_SORTFILES * SORT_NAME; 1056 if (ENABLE_FEATURE_LS_SORTFILES)
1057 all_fmt = SORT_NAME;
1053 1058
1054#if ENABLE_FEATURE_AUTOWIDTH 1059#if ENABLE_FEATURE_AUTOWIDTH
1055 /* obtain the terminal width */ 1060 /* obtain the terminal width */
@@ -1090,14 +1095,12 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
1090 if (flags & TIME_MASK) 1095 if (flags & TIME_MASK)
1091 all_fmt &= ~TIME_MASK; 1096 all_fmt &= ~TIME_MASK;
1092 1097
1093 if (flags & LIST_CONTEXT)
1094 all_fmt |= STYLE_SINGLE;
1095 all_fmt |= flags; 1098 all_fmt |= flags;
1096 } 1099 }
1097 } 1100 }
1098 1101
1099#if ENABLE_FEATURE_LS_COLOR 1102#if ENABLE_FEATURE_LS_COLOR
1100 /* find color bit value - last position for short getopt */ 1103 /* set show_color = 1/0 */
1101 if (ENABLE_FEATURE_LS_COLOR_IS_DEFAULT && isatty(STDOUT_FILENO)) { 1104 if (ENABLE_FEATURE_LS_COLOR_IS_DEFAULT && isatty(STDOUT_FILENO)) {
1102 char *p = getenv("LS_COLORS"); 1105 char *p = getenv("LS_COLORS");
1103 /* LS_COLORS is unset, or (not empty && not "none") ? */ 1106 /* LS_COLORS is unset, or (not empty && not "none") ? */
@@ -1130,11 +1133,8 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
1130 if (all_fmt & TIME_ACCESS) 1133 if (all_fmt & TIME_ACCESS)
1131 all_fmt = (all_fmt & ~SORT_MASK) | SORT_ATIME; 1134 all_fmt = (all_fmt & ~SORT_MASK) | SORT_ATIME;
1132 } 1135 }
1133 if ((all_fmt & STYLE_MASK) != STYLE_LONG) /* only for long list */ 1136 if ((all_fmt & STYLE_MASK) != STYLE_LONG) /* not -l? */
1134 all_fmt &= ~(LIST_ID_NUMERIC|LIST_ID_NAME|LIST_FULLTIME); 1137 all_fmt &= ~(LIST_ID_NUMERIC|LIST_ID_NAME|LIST_FULLTIME);
1135 if (ENABLE_FEATURE_LS_USERNAME)
1136 if ((all_fmt & STYLE_MASK) == STYLE_LONG && (all_fmt & LIST_ID_NUMERIC))
1137 all_fmt &= ~LIST_ID_NAME; /* don't list names if numeric uid */
1138 1138
1139 /* choose a display format if one was not already specified by an option */ 1139 /* choose a display format if one was not already specified by an option */
1140 if (!(all_fmt & STYLE_MASK)) 1140 if (!(all_fmt & STYLE_MASK))
@@ -1153,7 +1153,10 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
1153 do { 1153 do {
1154 cur = my_stat(*argv, *argv, 1154 cur = my_stat(*argv, *argv,
1155 /* follow links on command line unless -l, -s or -F: */ 1155 /* follow links on command line unless -l, -s or -F: */
1156 !((all_fmt & (STYLE_LONG|LIST_BLOCKS)) || (option_mask32 & OPT_F)) 1156 !((all_fmt & STYLE_MASK) == STYLE_LONG
1157 || (all_fmt & LIST_BLOCKS)
1158 || (option_mask32 & OPT_F)
1159 )
1157 /* ... or if -H: */ 1160 /* ... or if -H: */
1158 || (option_mask32 & OPT_H) 1161 || (option_mask32 & OPT_H)
1159 ); 1162 );
diff --git a/coreutils/printenv.c b/coreutils/printenv.c
index 33be5c096..d0fb71636 100644
--- a/coreutils/printenv.c
+++ b/coreutils/printenv.c
@@ -19,9 +19,14 @@ int printenv_main(int argc UNUSED_PARAM, char **argv)
19 19
20 /* no variables specified, show whole env */ 20 /* no variables specified, show whole env */
21 if (!argv[1]) { 21 if (!argv[1]) {
22 int e = 0; 22 char **e = environ;
23 while (environ[e]) 23
24 puts(environ[e++]); 24 /* environ can be NULL! (for example, after clearenv())
25 * Check for that:
26 */
27 if (e)
28 while (*e)
29 puts(*e++);
25 } else { 30 } else {
26 /* search for specified variables and print them out if found */ 31 /* search for specified variables and print them out if found */
27 char *arg, *env; 32 char *arg, *env;
diff --git a/coreutils/split.c b/coreutils/split.c
index db5a1727a..79316ed74 100644
--- a/coreutils/split.c
+++ b/coreutils/split.c
@@ -32,7 +32,7 @@ static char *next_file(char *old, unsigned suffix_len)
32 unsigned i = 1; 32 unsigned i = 1;
33 char *curr; 33 char *curr;
34 34
35 do { 35 while (1) {
36 curr = old + end - i; 36 curr = old + end - i;
37 if (*curr < 'z') { 37 if (*curr < 'z') {
38 *curr += 1; 38 *curr += 1;
@@ -43,7 +43,7 @@ static char *next_file(char *old, unsigned suffix_len)
43 return NULL; 43 return NULL;
44 } 44 }
45 *curr = 'a'; 45 *curr = 'a';
46 } while (1); 46 }
47 47
48 return old; 48 return old;
49} 49}
diff --git a/coreutils/test.c b/coreutils/test.c
index caecd7d02..cb15ed725 100644
--- a/coreutils/test.c
+++ b/coreutils/test.c
@@ -45,7 +45,7 @@
45/* This is a NOFORK applet. Be very careful! */ 45/* This is a NOFORK applet. Be very careful! */
46 46
47/* test_main() is called from shells, and we need to be extra careful here. 47/* test_main() is called from shells, and we need to be extra careful here.
48 * This is true regardless of PREFER_APPLETS and STANDALONE_SHELL 48 * This is true regardless of PREFER_APPLETS and SH_STANDALONE
49 * state. */ 49 * state. */
50 50
51/* test(1) accepts the following grammar: 51/* test(1) accepts the following grammar:
diff --git a/coreutils/tr.c b/coreutils/tr.c
index 21d77ef95..5b2b9a9a4 100644
--- a/coreutils/tr.c
+++ b/coreutils/tr.c
@@ -324,5 +324,11 @@ int tr_main(int argc UNUSED_PARAM, char **argv)
324 str2[out_index++] = last = coded; 324 str2[out_index++] = last = coded;
325 } 325 }
326 326
327 if (ENABLE_FEATURE_CLEAN_UP) {
328 free(vector);
329 free(str2);
330 free(str1);
331 }
332
327 return EXIT_SUCCESS; 333 return EXIT_SUCCESS;
328} 334}