# define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
#endif
+#if defined _DIRENT_HAVE_D_TYPE || defined DTTOIF
+# define HAVE_STRUCT_DIRENT_D_TYPE 1
+#else
+# define HAVE_STRUCT_DIRENT_D_TYPE 0
+#endif
+
enum filetype
{
+#if HAVE_STRUCT_DIRENT_D_TYPE
+ unknown = DT_UNKNOWN,
+ fifo = DT_FIFO,
+ chardev = DT_CHR,
+ directory = DT_DIR,
+ blockdev = DT_BLK,
+ normal = DT_REG,
+ symbolic_link = DT_LNK,
+ sock = DT_SOCK,
+ arg_directory = 100
+#else
symbolic_link,
directory,
arg_directory, /* Directory given as command line arg. */
normal /* All others. */
+#endif
};
struct fileinfo
const struct fileinfo *file1));
static int decode_switches PARAMS ((int argc, char **argv));
static int file_interesting PARAMS ((const struct dirent *next));
-static uintmax_t gobble_file PARAMS ((const char *name, int explicit_arg,
- const char *dirname));
+static uintmax_t gobble_file PARAMS ((const char *name, enum filetype type,
+ int explicit_arg, const char *dirname));
static void print_color_indicator PARAMS ((const char *name, unsigned int mode,
int linkok));
static void put_indicator PARAMS ((const struct bin_str *ind));
static int format_needs_stat;
+/* Similar to `format_needs_stat', but set if only the file type is
+ needed. */
+
+static int format_needs_type;
+
/* The exit status to use if we don't get any fatal errors. */
static int exit_status;
format_needs_stat = sort_type == sort_time || sort_type == sort_size
|| format == long_format
- || trace_links || trace_dirs || indicator_style != none
- || print_block_size || print_inode || print_with_color;
+ || trace_links || trace_dirs || print_block_size || print_inode;
+ format_needs_type = (format_needs_stat == 0
+ && (print_with_color || indicator_style != none));
if (dired && format == long_format)
{
dir_defaulted = 0;
for (; i < argc; i++)
{
- gobble_file (argv[i], 1, "");
+ gobble_file (argv[i], unknown, 1, "");
}
if (dir_defaulted)
{
if (immediate_dirs)
- gobble_file (".", 1, "");
+ gobble_file (".", unknown, 1, "");
else
queue_directory (".", 0);
}
while ((next = readdir (reading)) != NULL)
if (file_interesting (next))
- total_blocks += gobble_file (next->d_name, 0, name);
+ {
+ enum filetype type = unknown;
+
+#if HAVE_STRUCT_DIRENT_D_TYPE
+ if (next->d_type == DT_DIR || next->d_type == DT_CHR
+ || next->d_type == DT_BLK || next->d_type == DT_SOCK
+ || next->d_type == DT_FIFO)
+ type = next->d_type;
+#endif
+ total_blocks += gobble_file (next->d_name, type, 0, name);
+ }
if (CLOSEDIR (reading))
{
Return the number of blocks that the file occupies. */
static uintmax_t
-gobble_file (const char *name, int explicit_arg, const char *dirname)
+gobble_file (const char *name, enum filetype type, int explicit_arg,
+ const char *dirname)
{
register uintmax_t blocks;
register int val;
files[files_index].linkmode = 0;
files[files_index].linkok = 0;
- if (explicit_arg || format_needs_stat)
+ if (explicit_arg || format_needs_stat
+ || (format_needs_type && type == unknown))
{
/* `path' is the absolute pathname of this file. */
}
}
else
- blocks = 0;
+ {
+ files[files_index].filetype = type;
+#if HAVE_STRUCT_DIRENT_D_TYPE
+ files[files_index].stat.st_mode = DTTOIF (type);
+#endif
+ blocks = 0;
+ }
files[files_index].name = xstrdup (name);
files_index++;