diff options
author | Jim Meyering <jim@meyering.net> | 2006-02-26 10:01:00 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2006-02-26 10:01:00 +0000 |
commit | 33eb3efe9fb6d7f72245ec8640cc6daf424810cf (patch) | |
tree | 4338ab76654fa875ada710bf718bf995af27b7ea | |
parent | 256239cd3da92c6dcc3868ce86a6535b308afd5d (diff) | |
download | coreutils-33eb3efe9fb6d7f72245ec8640cc6daf424810cf.tar.xz |
In ls, avoid calling stat for --inode (-i), when possible.
(main): Prefer dirent.d_ino to stat when possible.
(gobble_file): Add inode argument.
(print_dir): Pass inode if available.
(usage): Remove inaccuracy.
-rw-r--r-- | src/ls.c | 53 |
1 files changed, 34 insertions, 19 deletions
@@ -231,7 +231,8 @@ static char *make_link_name (char const *name, char const *linkname); static int decode_switches (int argc, char **argv); static bool file_ignored (char const *name); static uintmax_t gobble_file (char const *name, enum filetype type, - bool command_line_arg, char const *dirname); + ino_t inode, bool command_line_arg, + char const *dirname); static void print_color_indicator (const char *name, mode_t mode, int linkok); static void put_indicator (const struct bin_str *ind); static void add_ignore_pattern (const char *pattern); @@ -1222,9 +1223,8 @@ main (int argc, char **argv) format_needs_stat = sort_type == sort_time || sort_type == sort_size || format == long_format - || dereference == DEREF_ALWAYS - || print_block_size || print_inode; - format_needs_type = (!format_needs_stat + || print_block_size; + format_needs_type = (! format_needs_stat && (recursive || print_with_color || indicator_style != none)); @@ -1245,13 +1245,13 @@ main (int argc, char **argv) if (n_files <= 0) { if (immediate_dirs) - gobble_file (".", directory, true, ""); + gobble_file (".", directory, NOT_AN_INODE_NUMBER, true, ""); else queue_directory (".", NULL, true); } else do - gobble_file (argv[i++], unknown, true, ""); + gobble_file (argv[i++], unknown, NOT_AN_INODE_NUMBER, true, ""); while (i < argc); if (files_index) @@ -2351,7 +2351,8 @@ print_dir (char const *name, char const *realname, bool command_line_arg) || next->d_type == DT_SOCK) type = next->d_type; #endif - total_blocks += gobble_file (next->d_name, type, false, name); + total_blocks += gobble_file (next->d_name, type, D_INO (next), + false, name); } } else if (errno != 0) @@ -2496,12 +2497,16 @@ clear_files (void) Return the number of blocks that the file occupies. */ static uintmax_t -gobble_file (char const *name, enum filetype type, bool command_line_arg, - char const *dirname) +gobble_file (char const *name, enum filetype type, ino_t inode, + bool command_line_arg, char const *dirname) { uintmax_t blocks; struct fileinfo *f; + /* An inode value prior to gobble_file necessarily came from readdir, + which is not used for command line arguments. */ + assert (! command_line_arg || inode == NOT_AN_INODE_NUMBER); + if (files_index == nfiles) { files = xnrealloc (files, nfiles, 2 * sizeof *files); @@ -2515,6 +2520,14 @@ gobble_file (char const *name, enum filetype type, bool command_line_arg, if (command_line_arg || format_needs_stat + || (print_inode + && (inode == NOT_AN_INODE_NUMBER + /* When dereferencing symlinks, the inode must come from + stat, but readdir provides the inode of lstat. Command + line dereferences are already taken care of by the above + assertion that the inode number is not yet known. */ + || (dereference == DEREF_ALWAYS + && (type == symbolic_link || type == unknown)))) || (format_needs_type && (type == unknown @@ -2617,8 +2630,8 @@ gobble_file (char const *name, enum filetype type, bool command_line_arg, f->linkok = true; /* Symbolic links to directories that are mentioned on the - command line are automatically traced if not being - listed as files. */ + command line are automatically traced if not being + listed as files. */ if (!command_line_arg || format == long_format || !S_ISDIR (linkstats.st_mode)) { @@ -2643,13 +2656,6 @@ gobble_file (char const *name, enum filetype type, bool command_line_arg, else f->filetype = normal; - { - char buf[INT_BUFSIZE_BOUND (uintmax_t)]; - int len = strlen (umaxtostr (f->stat.st_ino, buf)); - if (inode_number_width < len) - inode_number_width = len; - } - blocks = ST_NBLOCKS (f->stat); { char buf[LONGEST_HUMAN_READABLE + 1]; @@ -2715,12 +2721,21 @@ gobble_file (char const *name, enum filetype type, bool command_line_arg, else { f->filetype = type; + f->stat.st_ino = inode; #if HAVE_STRUCT_DIRENT_D_TYPE && defined DTTOIF f->stat.st_mode = DTTOIF (type); #endif blocks = 0; } + if (print_inode) + { + char buf[INT_BUFSIZE_BOUND (uintmax_t)]; + int len = strlen (umaxtostr (f->stat.st_ino, buf)); + if (inode_number_width < len) + inode_number_width = len; + } + f->name = xstrdup (name); files_index++; @@ -4162,7 +4177,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\ --indicator-style=WORD append indicator with style WORD to entry names:\n\ none (default), slash (-p),\n\ file-type (--file-type), classify (-F)\n\ - -i, --inode with -l, print the index number of each file\n\ + -i, --inode print the index number of each file\n\ -I, --ignore=PATTERN do not list implied entries matching shell PATTERN\n\ -k like --block-size=1K\n\ "), stdout); |