diff --git a/Base/usr/share/man/man1/listdir.md b/Base/usr/share/man/man1/listdir.md new file mode 100644 index 0000000000..bb63324537 --- /dev/null +++ b/Base/usr/share/man/man1/listdir.md @@ -0,0 +1,43 @@ +## Name + +lsdir - list directory entries + +## Synopsis + +```**sh +# lsdir [options...] [path...] +``` + +## Description + +This utility will list all directory entries of a given path (or list of paths) +and print their inode number and file type (in either POSIX DT_* format or human readable). + +The utility uses `LibCore` `DirIterator` object and restrict its functionality +to the `get_dir_entries` syscall only, to get the raw values of each directory +entry. + +## Options + +* `-P`, `--posix-names`: Show POSIX names for file types +* `-t`, `--total-entries-count`: Print count of listed entries when traversing a directory + +## Arguments + +* `path`: Directory to list + +## Examples + +```sh +# List directory entries of working directory +$ lsdir +# List directory entries of /proc directory +$ lsdir /proc +# List directory entries of /proc directory with POSIX names for file types +$ lsdir -P /proc +# List directory entries of /proc directory and print in the end the count of traversed entries +$ lsdir -t /proc +``` + +## See also +* [`ls`(1)](help://man/1/ls) diff --git a/Userland/Utilities/listdir.cpp b/Userland/Utilities/listdir.cpp new file mode 100644 index 0000000000..1a9f8910d1 --- /dev/null +++ b/Userland/Utilities/listdir.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2024, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +static bool flag_show_unix_posix_file_type = false; +static bool flag_show_total_count = false; + +ErrorOr serenity_main(Main::Arguments arguments) +{ + TRY(Core::System::pledge("stdio rpath")); + + Vector paths; + + Core::ArgsParser args_parser; + args_parser.set_general_help("List Dirent entries in a directory."); + args_parser.add_option(flag_show_unix_posix_file_type, "Show POSIX names for file types", "posix-names", 'P'); + args_parser.add_option(flag_show_total_count, "Show total count for each directory being iterated", "total-entries-count", 't'); + args_parser.add_positional_argument(paths, "Directory to list", "path", Core::ArgsParser::Required::No); + args_parser.parse(arguments); + + if (paths.is_empty()) + paths.append("."sv); + + for (auto& path : paths) { + Core::DirIterator di(path, Core::DirIterator::NoStat); + if (di.has_error()) { + auto error = di.error(); + warnln("Failed to open {} - {}", path, error); + return error; + } + + outln("Traversing {}", path); + size_t count = 0; + + Function name_from_directory_entry_type; + if (flag_show_unix_posix_file_type) + name_from_directory_entry_type = Core::DirectoryEntry::posix_name_from_directory_entry_type; + else + name_from_directory_entry_type = Core::DirectoryEntry::representative_name_from_directory_entry_type; + + while (di.has_next()) { + auto dir_entry = di.next(); + if (dir_entry.has_value()) { + outln(" {} (Type: {}, Inode number: {})", + dir_entry.value().name, + name_from_directory_entry_type(dir_entry.value().type), + dir_entry.value().inode_number); + count++; + } + } + if (flag_show_total_count) + outln("Directory {} has {} which has being listed during the program runtime", path, count); + } + + return 0; +}