ls: replace -e with --full-time, add --group-directories-first, delete -K
-K and -e were non-standard function old new delta static.ls_longopts 9 47 +38 ls_main 748 776 +28 display_single 901 928 +27 sortcmp 254 258 +4 ls_options 32 31 -1 opt_flags 100 96 -4 packed_usage 31032 30977 -55 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 4/3 up/down: 97/-60) Total: 37 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
12389889c0
commit
194b2ebd2a
126
coreutils/ls.c
126
coreutils/ls.c
@ -130,17 +130,20 @@
|
||||
//usage: "\n -i List inode numbers"
|
||||
//usage: "\n -n List numeric UIDs and GIDs instead of names"
|
||||
//usage: "\n -s List allocated blocks"
|
||||
//usage: IF_FEATURE_LS_TIMESTAMPS(
|
||||
//usage: "\n -e List full date and time"
|
||||
//usage: )
|
||||
//usage: IF_FEATURE_LS_TIMESTAMPS(IF_LONG_OPTS(
|
||||
//usage: "\n --full-time List full date and time"
|
||||
//usage: ))
|
||||
//usage: IF_FEATURE_HUMAN_READABLE(
|
||||
//usage: "\n -h List sizes in human readable format (1K 243M 2G)"
|
||||
//usage: )
|
||||
//usage: IF_FEATURE_LS_SORTFILES(
|
||||
//usage: "\n -r Sort in reverse order"
|
||||
//usage: IF_LONG_OPTS(
|
||||
//usage: "\n --group-directories-first"
|
||||
//usage: )
|
||||
//usage: "\n -S Sort by size"
|
||||
//usage: "\n -X Sort by extension"
|
||||
//usage: "\n -v Sort by version"
|
||||
//usage: "\n -r Reverse sort order"
|
||||
//usage: )
|
||||
//usage: IF_FEATURE_LS_TIMESTAMPS(
|
||||
//usage: "\n -c With -l: sort by ctime"
|
||||
@ -149,7 +152,6 @@
|
||||
//usage: )
|
||||
//usage: IF_SELINUX(
|
||||
//usage: "\n -k List security context"
|
||||
//usage: "\n -K List security context in long format"
|
||||
//usage: "\n -Z List security context and permission"
|
||||
//usage: )
|
||||
//usage: IF_FEATURE_LS_WIDTH(
|
||||
@ -230,16 +232,16 @@ TIME_MASK = (3 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS,
|
||||
|
||||
/* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */
|
||||
SORT_REVERSE = 1 << 23,
|
||||
SORT_DIRS_FIRST = 1 << 24,
|
||||
|
||||
SORT_NAME = 0, /* sort by file name */
|
||||
SORT_SIZE = 1 << 24, /* sort by file size */
|
||||
SORT_ATIME = 2 << 24, /* sort by last access time */
|
||||
SORT_CTIME = 3 << 24, /* sort by last change time */
|
||||
SORT_MTIME = 4 << 24, /* sort by last modification time */
|
||||
SORT_VERSION = 5 << 24, /* sort by version */
|
||||
SORT_EXT = 6 << 24, /* sort by file name extension */
|
||||
SORT_DIR = 7 << 24, /* sort by file or directory */
|
||||
SORT_MASK = (7 << 24) * ENABLE_FEATURE_LS_SORTFILES,
|
||||
SORT_SIZE = 1 << 25, /* sort by file size */
|
||||
SORT_ATIME = 2 << 25, /* sort by last access time */
|
||||
SORT_CTIME = 3 << 25, /* sort by last change time */
|
||||
SORT_MTIME = 4 << 25, /* sort by last modification time */
|
||||
SORT_VERSION = 5 << 25, /* sort by version */
|
||||
SORT_EXT = 6 << 25, /* sort by file name extension */
|
||||
SORT_MASK = (7 << 25) * ENABLE_FEATURE_LS_SORTFILES,
|
||||
|
||||
LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \
|
||||
LIST_DATE_TIME | LIST_SYMLINK,
|
||||
@ -249,26 +251,24 @@ LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \
|
||||
/* -gnsxA Std options, busybox always supports */
|
||||
/* -Q GNU option, busybox always supports */
|
||||
/* -k SELinux option, busybox always supports (ignores if !SELinux) */
|
||||
/* Std has -k which means "show sizes in kbytes" */
|
||||
/* Std has -k which means "for -s, show sizes in kbytes" */
|
||||
/* Seems to only affect "POSIXLY_CORRECT=1 ls -sk" */
|
||||
/* since otherwise -s shows kbytes anyway */
|
||||
/* -LHRctur Std options, busybox optionally supports */
|
||||
/* -Fp Std options, busybox optionally supports */
|
||||
/* -SXvhTw GNU options, busybox optionally supports */
|
||||
/* -T WIDTH Ignored (we don't use tabs on output) */
|
||||
/* -KZ SELinux mandated options, busybox optionally supports */
|
||||
/* (coreutils 8.4 has no -K, remove it?) */
|
||||
/* -e I think we made this one up (looks similar to GNU --full-time) */
|
||||
/* We already used up all 32 bits, if we need to add more, candidates for removal: */
|
||||
/* -K, -T, -e (add --full-time instead) */
|
||||
/* -Z SELinux mandated option, busybox optionally supports */
|
||||
static const char ls_options[] ALIGN1 =
|
||||
"Cadil1gnsxQAk" /* 13 opts, total 13 */
|
||||
IF_FEATURE_LS_TIMESTAMPS("cetu") /* 4, 17 */
|
||||
IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 21 */
|
||||
IF_FEATURE_LS_FILETYPES("Fp") /* 2, 23 */
|
||||
IF_FEATURE_LS_RECURSIVE("R") /* 1, 24 */
|
||||
IF_SELINUX("KZ") /* 2, 26 */
|
||||
IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 28 */
|
||||
IF_FEATURE_HUMAN_READABLE("h") /* 1, 29 */
|
||||
IF_FEATURE_LS_WIDTH("T:w:") /* 2, 31 */
|
||||
IF_FEATURE_LS_TIMESTAMPS("ctu") /* 3, 16 */
|
||||
IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 20 */
|
||||
IF_FEATURE_LS_FILETYPES("Fp") /* 2, 22 */
|
||||
IF_FEATURE_LS_RECURSIVE("R") /* 1, 23 */
|
||||
IF_SELINUX("Z") /* 1, 24 */
|
||||
IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 26 */
|
||||
IF_FEATURE_HUMAN_READABLE("h") /* 1, 27 */
|
||||
IF_FEATURE_LS_WIDTH("T:w:") /* 2, 29 */
|
||||
/* with --color, we use all 32 bits */;
|
||||
enum {
|
||||
//OPT_C = (1 << 0),
|
||||
@ -286,27 +286,26 @@ enum {
|
||||
//OPT_k = (1 << 12),
|
||||
|
||||
OPTBIT_c = 13,
|
||||
OPTBIT_e,
|
||||
OPTBIT_t,
|
||||
OPTBIT_u,
|
||||
OPTBIT_S = OPTBIT_c + 4 * ENABLE_FEATURE_LS_TIMESTAMPS,
|
||||
OPTBIT_X, /* 18 */
|
||||
OPTBIT_S = OPTBIT_c + 3 * ENABLE_FEATURE_LS_TIMESTAMPS,
|
||||
OPTBIT_X, /* 17 */
|
||||
OPTBIT_r,
|
||||
OPTBIT_v,
|
||||
OPTBIT_F = OPTBIT_S + 4 * ENABLE_FEATURE_LS_SORTFILES,
|
||||
OPTBIT_p, /* 22 */
|
||||
OPTBIT_p, /* 21 */
|
||||
OPTBIT_R = OPTBIT_F + 2 * ENABLE_FEATURE_LS_FILETYPES,
|
||||
OPTBIT_K = OPTBIT_R + 1 * ENABLE_FEATURE_LS_RECURSIVE,
|
||||
OPTBIT_Z, /* 25 */
|
||||
OPTBIT_L = OPTBIT_K + 2 * ENABLE_SELINUX,
|
||||
OPTBIT_H, /* 27 */
|
||||
OPTBIT_Z = OPTBIT_R + 1 * ENABLE_FEATURE_LS_RECURSIVE,
|
||||
OPTBIT_L = OPTBIT_Z + 2 * ENABLE_SELINUX,
|
||||
OPTBIT_H, /* 25 */
|
||||
OPTBIT_h = OPTBIT_L + 2 * ENABLE_FEATURE_LS_FOLLOWLINKS,
|
||||
OPTBIT_T = OPTBIT_h + 1 * ENABLE_FEATURE_HUMAN_READABLE,
|
||||
OPTBIT_w, /* 30 */
|
||||
OPTBIT_w, /* 28 */
|
||||
OPTBIT_color = OPTBIT_T + 2 * ENABLE_FEATURE_LS_WIDTH,
|
||||
OPTBIT_dirs_first = OPTBIT_color + 1 * ENABLE_FEATURE_LS_COLOR,
|
||||
OPTBIT_full_time,
|
||||
|
||||
OPT_c = (1 << OPTBIT_c) * ENABLE_FEATURE_LS_TIMESTAMPS,
|
||||
OPT_e = (1 << OPTBIT_e) * ENABLE_FEATURE_LS_TIMESTAMPS,
|
||||
OPT_t = (1 << OPTBIT_t) * ENABLE_FEATURE_LS_TIMESTAMPS,
|
||||
OPT_u = (1 << OPTBIT_u) * ENABLE_FEATURE_LS_TIMESTAMPS,
|
||||
OPT_S = (1 << OPTBIT_S) * ENABLE_FEATURE_LS_SORTFILES,
|
||||
@ -316,7 +315,6 @@ enum {
|
||||
OPT_F = (1 << OPTBIT_F) * ENABLE_FEATURE_LS_FILETYPES,
|
||||
OPT_p = (1 << OPTBIT_p) * ENABLE_FEATURE_LS_FILETYPES,
|
||||
OPT_R = (1 << OPTBIT_R) * ENABLE_FEATURE_LS_RECURSIVE,
|
||||
OPT_K = (1 << OPTBIT_K) * ENABLE_SELINUX,
|
||||
OPT_Z = (1 << OPTBIT_Z) * ENABLE_SELINUX,
|
||||
OPT_L = (1 << OPTBIT_L) * ENABLE_FEATURE_LS_FOLLOWLINKS,
|
||||
OPT_H = (1 << OPTBIT_H) * ENABLE_FEATURE_LS_FOLLOWLINKS,
|
||||
@ -324,6 +322,8 @@ enum {
|
||||
OPT_T = (1 << OPTBIT_T) * ENABLE_FEATURE_LS_WIDTH,
|
||||
OPT_w = (1 << OPTBIT_w) * ENABLE_FEATURE_LS_WIDTH,
|
||||
OPT_color = (1 << OPTBIT_color ) * ENABLE_FEATURE_LS_COLOR,
|
||||
OPT_dirs_first = (1 << OPTBIT_dirs_first) * ENABLE_LONG_OPTS,
|
||||
OPT_full_time = (1 << OPTBIT_full_time ) * ENABLE_LONG_OPTS,
|
||||
};
|
||||
|
||||
/* TODO: simple toggles may be stored as OPT_xxx bits instead */
|
||||
@ -343,7 +343,6 @@ static const uint32_t opt_flags[] = {
|
||||
ENABLE_SELINUX * (LIST_CONTEXT|STYLE_SINGLE), /* k (ignored if !SELINUX) */
|
||||
#if ENABLE_FEATURE_LS_TIMESTAMPS
|
||||
TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */
|
||||
LIST_FULLTIME, /* e */
|
||||
ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */
|
||||
TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */
|
||||
#endif
|
||||
@ -361,7 +360,6 @@ static const uint32_t opt_flags[] = {
|
||||
DISP_RECURSIVE, /* R */
|
||||
#endif
|
||||
#if ENABLE_SELINUX
|
||||
LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME|STYLE_SINGLE, /* K */
|
||||
LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT|STYLE_SINGLE, /* Z */
|
||||
#endif
|
||||
(1U << 31)
|
||||
@ -634,21 +632,22 @@ static NOINLINE unsigned display_single(const struct dnode *dn)
|
||||
}
|
||||
#if ENABLE_FEATURE_LS_TIMESTAMPS
|
||||
if (G.all_fmt & (LIST_FULLTIME|LIST_DATE_TIME)) {
|
||||
char *filetime;
|
||||
const time_t *ttime = &dn->dn_mtime;
|
||||
if (G.all_fmt & TIME_ACCESS)
|
||||
ttime = &dn->dn_atime;
|
||||
if (G.all_fmt & TIME_CHANGE)
|
||||
ttime = &dn->dn_ctime;
|
||||
filetime = ctime(ttime);
|
||||
/* filetime's format: "Wed Jun 30 21:49:08 1993\n" */
|
||||
if (G.all_fmt & LIST_FULLTIME) { /* -e */
|
||||
/* Note: coreutils 8.4 ls --full-time prints:
|
||||
if (G.all_fmt & LIST_FULLTIME) { /* --full-time */
|
||||
/* coreutils 8.4 ls --full-time prints:
|
||||
* 2009-07-13 17:49:27.000000000 +0200
|
||||
*/
|
||||
column += printf("%.24s ", filetime);
|
||||
char buf[sizeof("YYYY-mm-dd HH:MM:SS TIMEZONE")];
|
||||
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z", localtime(ttime));
|
||||
column += printf("%s ", buf);
|
||||
} else { /* LIST_DATE_TIME */
|
||||
/* G.current_time_t ~== time(NULL) */
|
||||
/* G.current_time_t is ~== time(NULL) */
|
||||
char *filetime = ctime(ttime);
|
||||
/* filetime's format: "Wed Jun 30 21:49:08 1993\n" */
|
||||
time_t age = G.current_time_t - *ttime;
|
||||
if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) {
|
||||
/* less than 6 months old */
|
||||
@ -943,6 +942,12 @@ static int sortcmp(const void *a, const void *b)
|
||||
dif = 0; /* assume SORT_NAME */
|
||||
// TODO: use pre-initialized function pointer
|
||||
// instead of branch forest
|
||||
if (G.all_fmt & SORT_DIRS_FIRST) {
|
||||
dif = S_ISDIR(d2->dn_mode) - S_ISDIR(d1->dn_mode);
|
||||
if (dif != 0)
|
||||
goto maybe_invert_and_ret;
|
||||
}
|
||||
|
||||
if (sort_opts == SORT_SIZE) {
|
||||
dif = (d2->dn_size - d1->dn_size);
|
||||
} else
|
||||
@ -955,9 +960,6 @@ static int sortcmp(const void *a, const void *b)
|
||||
if (sort_opts == SORT_MTIME) {
|
||||
dif = (d2->dn_mtime - d1->dn_mtime);
|
||||
} else
|
||||
if (sort_opts == SORT_DIR) {
|
||||
dif = S_ISDIR(d2->dn_mode) - S_ISDIR(d1->dn_mode);
|
||||
} else
|
||||
#if defined(HAVE_STRVERSCMP) && HAVE_STRVERSCMP == 1
|
||||
if (sort_opts == SORT_VERSION) {
|
||||
dif = strverscmp(d1->name, d2->name);
|
||||
@ -982,7 +984,7 @@ static int sortcmp(const void *a, const void *b)
|
||||
dif = 1 | (int)((uoff_t)dif >> BITS_TO_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
maybe_invert_and_ret:
|
||||
return (G.all_fmt & SORT_REVERSE) ? -(int)dif : (int)dif;
|
||||
}
|
||||
|
||||
@ -1157,7 +1159,10 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
|
||||
* (and substrings: "--color=alwa" work too)
|
||||
*/
|
||||
static const char ls_longopts[] ALIGN1 =
|
||||
"color\0" Optional_argument "\xff"; /* no short equivalent */
|
||||
"color\0" Optional_argument "\xff" /* no short equivalent */
|
||||
"group-directories-first\0" No_argument "\xfe"
|
||||
"full-time\0" No_argument "\xfd"
|
||||
;
|
||||
static const char color_str[] ALIGN1 =
|
||||
"always\0""yes\0""force\0"
|
||||
"auto\0""tty\0""if-tty\0";
|
||||
@ -1182,8 +1187,8 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
|
||||
/* process options */
|
||||
IF_FEATURE_LS_COLOR(applet_long_options = ls_longopts;)
|
||||
opt_complementary =
|
||||
/* -e implies -l */
|
||||
IF_FEATURE_LS_TIMESTAMPS("el")
|
||||
/* --full-time implies -l */
|
||||
IF_FEATURE_LS_TIMESTAMPS(IF_LONG_OPTS("\xfd""l"))
|
||||
/* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html:
|
||||
* in some pairs of opts, only last one takes effect:
|
||||
*/
|
||||
@ -1200,6 +1205,15 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
|
||||
IF_FEATURE_LS_WIDTH(, NULL, &G_terminal_width)
|
||||
IF_FEATURE_LS_COLOR(, &color_opt)
|
||||
);
|
||||
#if 0 /* option bits debug */
|
||||
bb_error_msg("opt:0x%08x H:%x color:%x dirs:%x", opt, OPT_H, OPT_color, OPT_dirs_first);
|
||||
if (opt & OPT_c ) bb_error_msg("-c");
|
||||
if (opt & OPT_H ) bb_error_msg("-H");
|
||||
if (opt & OPT_color ) bb_error_msg("--color");
|
||||
if (opt & OPT_dirs_first) bb_error_msg("--group-directories-first");
|
||||
if (opt & OPT_full_time ) bb_error_msg("--full-time");
|
||||
exit(0);
|
||||
#endif
|
||||
for (i = 0; opt_flags[i] != (1U << 31); i++) {
|
||||
if (opt & (1 << i)) {
|
||||
uint32_t flags = opt_flags[i];
|
||||
@ -1239,6 +1253,10 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (opt & OPT_dirs_first)
|
||||
G.all_fmt |= SORT_DIRS_FIRST;
|
||||
if (opt & OPT_full_time)
|
||||
G.all_fmt |= LIST_FULLTIME;
|
||||
|
||||
/* sort out which command line options take precedence */
|
||||
if (ENABLE_FEATURE_LS_RECURSIVE && (G.all_fmt & DISP_NOLIST))
|
||||
|
Loading…
Reference in New Issue
Block a user