ls: more correct handling of -c, -u
function old new delta my_stat 302 318 +16 packed_usage 30977 30969 -8 display_single 928 910 -18 sortcmp 258 228 -30 ls_main 776 732 -44 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/4 up/down: 16/-100) Total: -84 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
194b2ebd2a
commit
f580baf94a
109
coreutils/ls.c
109
coreutils/ls.c
@ -101,11 +101,10 @@
|
||||
//usage: IF_FEATURE_LS_FOLLOWLINKS("LH")
|
||||
//usage: IF_FEATURE_LS_RECURSIVE("R")
|
||||
//usage: IF_FEATURE_LS_FILETYPES("Fp") "lins"
|
||||
//usage: IF_FEATURE_LS_TIMESTAMPS("e")
|
||||
//usage: IF_FEATURE_HUMAN_READABLE("h")
|
||||
//usage: IF_FEATURE_LS_SORTFILES("rSXv")
|
||||
//usage: IF_FEATURE_LS_TIMESTAMPS("ctu")
|
||||
//usage: IF_SELINUX("kKZ") "]"
|
||||
//usage: IF_SELINUX("kZ") "]"
|
||||
//usage: IF_FEATURE_LS_WIDTH(" [-w WIDTH]") " [FILE]..."
|
||||
//usage:#define ls_full_usage "\n\n"
|
||||
//usage: "List directory contents\n"
|
||||
@ -130,6 +129,10 @@
|
||||
//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 -c List ctime"
|
||||
//usage: "\n -u List atime"
|
||||
//usage: )
|
||||
//usage: IF_FEATURE_LS_TIMESTAMPS(IF_LONG_OPTS(
|
||||
//usage: "\n --full-time List full date and time"
|
||||
//usage: ))
|
||||
@ -143,13 +146,13 @@
|
||||
//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"
|
||||
//usage: "\n -t With -l: sort by mtime"
|
||||
//usage: "\n -u With -l: sort by atime"
|
||||
//usage: "\n -t Sort by mtime"
|
||||
//usage: "\n -tc Sort by ctime"
|
||||
//usage: "\n -tu Sort by atime"
|
||||
//usage: )
|
||||
//usage: "\n -r Reverse sort order"
|
||||
//usage: IF_SELINUX(
|
||||
//usage: "\n -k List security context"
|
||||
//usage: "\n -Z List security context and permission"
|
||||
@ -225,22 +228,15 @@ STYLE_LONG = 2 << 19, /* one record per line, extended info */
|
||||
STYLE_SINGLE = 3 << 19, /* one record per line */
|
||||
STYLE_MASK = STYLE_SINGLE,
|
||||
|
||||
/* which of the three times will be used */
|
||||
TIME_CHANGE = (1 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS,
|
||||
TIME_ACCESS = (2 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS,
|
||||
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 << 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_TIME = 2 << 25, /* sort by {a,m,c}time */
|
||||
SORT_VERSION = 3 << 25, /* sort by version */
|
||||
SORT_EXT = 4 << 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 | \
|
||||
@ -268,14 +264,14 @@ static const char ls_options[] ALIGN1 =
|
||||
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 */;
|
||||
IF_FEATURE_LS_WIDTH("T:w:") /* 2, 29 */
|
||||
;
|
||||
enum {
|
||||
//OPT_C = (1 << 0),
|
||||
//OPT_a = (1 << 1),
|
||||
//OPT_d = (1 << 2),
|
||||
//OPT_i = (1 << 3),
|
||||
//OPT_l = (1 << 4),
|
||||
OPT_l = (1 << 4),
|
||||
//OPT_1 = (1 << 5),
|
||||
OPT_g = (1 << 6),
|
||||
//OPT_n = (1 << 7),
|
||||
@ -301,9 +297,10 @@ enum {
|
||||
OPTBIT_h = OPTBIT_L + 2 * ENABLE_FEATURE_LS_FOLLOWLINKS,
|
||||
OPTBIT_T = OPTBIT_h + 1 * ENABLE_FEATURE_HUMAN_READABLE,
|
||||
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,
|
||||
OPTBIT_full_time = OPTBIT_T + 2 * ENABLE_FEATURE_LS_WIDTH,
|
||||
OPTBIT_dirs_first,
|
||||
OPTBIT_color, /* 31 */
|
||||
/* with long opts, we use all 32 bits */
|
||||
|
||||
OPT_c = (1 << OPTBIT_c) * ENABLE_FEATURE_LS_TIMESTAMPS,
|
||||
OPT_t = (1 << OPTBIT_t) * ENABLE_FEATURE_LS_TIMESTAMPS,
|
||||
@ -321,9 +318,9 @@ enum {
|
||||
OPT_h = (1 << OPTBIT_h) * ENABLE_FEATURE_HUMAN_READABLE,
|
||||
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,
|
||||
OPT_dirs_first = (1 << OPTBIT_dirs_first) * ENABLE_LONG_OPTS,
|
||||
OPT_color = (1 << OPTBIT_color ) * ENABLE_FEATURE_LS_COLOR,
|
||||
};
|
||||
|
||||
/* TODO: simple toggles may be stored as OPT_xxx bits instead */
|
||||
@ -342,9 +339,9 @@ static const uint32_t opt_flags[] = {
|
||||
DISP_HIDDEN, /* A */
|
||||
ENABLE_SELINUX * (LIST_CONTEXT|STYLE_SINGLE), /* k (ignored if !SELINUX) */
|
||||
#if ENABLE_FEATURE_LS_TIMESTAMPS
|
||||
TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */
|
||||
ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */
|
||||
TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */
|
||||
0, /* c - handled via OPT_c */
|
||||
(ENABLE_FEATURE_LS_SORTFILES * SORT_TIME), /* t */
|
||||
0, /* u - handled via OPT_u */
|
||||
#endif
|
||||
#if ENABLE_FEATURE_LS_SORTFILES
|
||||
SORT_SIZE, /* S */
|
||||
@ -396,9 +393,7 @@ struct dnode {
|
||||
mode_t dn_mode; /* obtained with lstat OR stat, depending on -L etc */
|
||||
off_t dn_size;
|
||||
#if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES
|
||||
time_t dn_atime;
|
||||
time_t dn_mtime;
|
||||
time_t dn_ctime;
|
||||
time_t dn_time;
|
||||
#endif
|
||||
ino_t dn_ino;
|
||||
blkcnt_t dn_blocks;
|
||||
@ -632,14 +627,11 @@ static NOINLINE unsigned display_single(const struct dnode *dn)
|
||||
}
|
||||
#if ENABLE_FEATURE_LS_TIMESTAMPS
|
||||
if (G.all_fmt & (LIST_FULLTIME|LIST_DATE_TIME)) {
|
||||
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;
|
||||
const time_t *ttime = &dn->dn_time;
|
||||
if (G.all_fmt & LIST_FULLTIME) { /* --full-time */
|
||||
/* coreutils 8.4 ls --full-time prints:
|
||||
* 2009-07-13 17:49:27.000000000 +0200
|
||||
* we don't show fractional seconds.
|
||||
*/
|
||||
char buf[sizeof("YYYY-mm-dd HH:MM:SS TIMEZONE")];
|
||||
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z", localtime(ttime));
|
||||
@ -820,9 +812,11 @@ static struct dnode *my_stat(const char *fullname, const char *name, int force_f
|
||||
cur->dn_mode = statbuf.st_mode ;
|
||||
cur->dn_size = statbuf.st_size ;
|
||||
#if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES
|
||||
cur->dn_atime = statbuf.st_atime ;
|
||||
cur->dn_mtime = statbuf.st_mtime ;
|
||||
cur->dn_ctime = statbuf.st_ctime ;
|
||||
cur->dn_time = statbuf.st_mtime ;
|
||||
if (option_mask32 & OPT_u)
|
||||
cur->dn_time = statbuf.st_atime;
|
||||
if (option_mask32 & OPT_c)
|
||||
cur->dn_time = statbuf.st_ctime;
|
||||
#endif
|
||||
cur->dn_ino = statbuf.st_ino ;
|
||||
cur->dn_blocks = statbuf.st_blocks;
|
||||
@ -951,14 +945,8 @@ static int sortcmp(const void *a, const void *b)
|
||||
if (sort_opts == SORT_SIZE) {
|
||||
dif = (d2->dn_size - d1->dn_size);
|
||||
} else
|
||||
if (sort_opts == SORT_ATIME) {
|
||||
dif = (d2->dn_atime - d1->dn_atime);
|
||||
} else
|
||||
if (sort_opts == SORT_CTIME) {
|
||||
dif = (d2->dn_ctime - d1->dn_ctime);
|
||||
} else
|
||||
if (sort_opts == SORT_MTIME) {
|
||||
dif = (d2->dn_mtime - d1->dn_mtime);
|
||||
if (sort_opts == SORT_TIME) {
|
||||
dif = (d2->dn_time - d1->dn_time);
|
||||
} else
|
||||
#if defined(HAVE_STRVERSCMP) && HAVE_STRVERSCMP == 1
|
||||
if (sort_opts == SORT_VERSION) {
|
||||
@ -1159,9 +1147,9 @@ 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 */
|
||||
"full-time\0" No_argument "\xff"
|
||||
"group-directories-first\0" No_argument "\xfe"
|
||||
"full-time\0" No_argument "\xfd"
|
||||
"color\0" Optional_argument "\xfd"
|
||||
;
|
||||
static const char color_str[] ALIGN1 =
|
||||
"always\0""yes\0""force\0"
|
||||
@ -1188,7 +1176,7 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
|
||||
IF_FEATURE_LS_COLOR(applet_long_options = ls_longopts;)
|
||||
opt_complementary =
|
||||
/* --full-time implies -l */
|
||||
IF_FEATURE_LS_TIMESTAMPS(IF_LONG_OPTS("\xfd""l"))
|
||||
IF_FEATURE_LS_TIMESTAMPS(IF_LONG_OPTS("\xff""l"))
|
||||
/* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html:
|
||||
* in some pairs of opts, only last one takes effect:
|
||||
*/
|
||||
@ -1206,8 +1194,9 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
|
||||
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);
|
||||
bb_error_msg("opt:0x%08x l:%x H:%x color:%x dirs:%x", opt, OPT_l, OPT_H, OPT_color, OPT_dirs_first);
|
||||
if (opt & OPT_c ) bb_error_msg("-c");
|
||||
if (opt & OPT_l ) bb_error_msg("-l");
|
||||
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");
|
||||
@ -1222,8 +1211,6 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
|
||||
G.all_fmt &= ~STYLE_MASK;
|
||||
if (flags & SORT_MASK)
|
||||
G.all_fmt &= ~SORT_MASK;
|
||||
if (flags & TIME_MASK)
|
||||
G.all_fmt &= ~TIME_MASK;
|
||||
|
||||
G.all_fmt |= flags;
|
||||
}
|
||||
@ -1261,14 +1248,18 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
|
||||
/* sort out which command line options take precedence */
|
||||
if (ENABLE_FEATURE_LS_RECURSIVE && (G.all_fmt & DISP_NOLIST))
|
||||
G.all_fmt &= ~DISP_RECURSIVE; /* no recurse if listing only dir */
|
||||
if (ENABLE_FEATURE_LS_TIMESTAMPS && ENABLE_FEATURE_LS_SORTFILES) {
|
||||
if (G.all_fmt & TIME_CHANGE)
|
||||
G.all_fmt = (G.all_fmt & ~SORT_MASK) | SORT_CTIME;
|
||||
if (G.all_fmt & TIME_ACCESS)
|
||||
G.all_fmt = (G.all_fmt & ~SORT_MASK) | SORT_ATIME;
|
||||
}
|
||||
if ((G.all_fmt & STYLE_MASK) != STYLE_LONG) /* not -l? */
|
||||
if ((G.all_fmt & STYLE_MASK) != STYLE_LONG) { /* not -l? */
|
||||
G.all_fmt &= ~(LIST_ID_NUMERIC|LIST_ID_NAME|LIST_FULLTIME);
|
||||
if (ENABLE_FEATURE_LS_TIMESTAMPS && ENABLE_FEATURE_LS_SORTFILES) {
|
||||
/* when to sort by time? -t[cu] sorts by time even with -l */
|
||||
/* (this is achieved by opt_flags[] element for -t) */
|
||||
/* without -l, bare -c or -u enable sort too */
|
||||
/* (with -l, bare -c or -u just select which time to show) */
|
||||
if (opt & (OPT_c|OPT_u)) {
|
||||
G.all_fmt = (G.all_fmt & ~SORT_MASK) | SORT_TIME;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* choose a display format if one was not already specified by an option */
|
||||
if (!(G.all_fmt & STYLE_MASK))
|
||||
|
Loading…
Reference in New Issue
Block a user