Skip to content

Commit

Permalink
Userland: ls: Add -d / --directory flag
Browse files Browse the repository at this point in the history
  • Loading branch information
bcoles authored and awesomekling committed Nov 10, 2020
1 parent 9b79ea7 commit 28abfd6
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 27 deletions.
3 changes: 2 additions & 1 deletion Base/usr/share/man/man1/ls.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ If no *path* argument is provided the current working directory is used.
* `--help`: Display this message
* `-a`, `--all`: Show dotfiles
* `-A`: Do not list implied . and .. directories
* `-B`, --ignore-backups`: Do not list implied entries ending with ~
* `-B`, `--ignore-backups`: Do not list implied entries ending with ~
* `-d`, `--directory`: List directories themselves, not their contents
* `-l`, `--long`: Display long info
* `-t`: Sort files by timestamp
* `-r`, `--reverse`: Reverse sort order
Expand Down
62 changes: 36 additions & 26 deletions Userland/ls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ static bool flag_long = false;
static bool flag_show_dotfiles = false;
static bool flag_show_almost_all_dotfiles = false;
static bool flag_ignore_backups = false;
static bool flag_list_directories_only = false;
static bool flag_show_inode = false;
static bool flag_print_numeric = false;
static bool flag_hide_group = false;
Expand Down Expand Up @@ -102,6 +103,7 @@ int main(int argc, char** argv)
args_parser.add_option(flag_show_dotfiles, "Show dotfiles", "all", 'a');
args_parser.add_option(flag_show_almost_all_dotfiles, "Do not list implied . and .. directories", nullptr, 'A');
args_parser.add_option(flag_ignore_backups, "Do not list implied entries ending with ~", "--ignore-backups", 'B');
args_parser.add_option(flag_list_directories_only, "List directories themselves, not their contents", "directory", 'd');
args_parser.add_option(flag_long, "Display long info", "long", 'l');
args_parser.add_option(flag_sort_by_timestamp, "Sort files by timestamp", nullptr, 't');
args_parser.add_option(flag_reverse_sort, "Reverse sort order", "reverse", 'r');
Expand Down Expand Up @@ -316,7 +318,26 @@ static bool print_filesystem_object(const String& path, const String& name, cons

static int do_file_system_object_long(const char* path)
{
Core::DirIterator di(path, !flag_show_dotfiles ? Core::DirIterator::SkipDots : Core::DirIterator::Flags::NoFlags);
if (flag_list_directories_only) {
struct stat stat;
int rc = lstat(path, &stat);
if (rc < 0) {
perror("lstat");
memset(&stat, 0, sizeof(stat));
}
if (print_filesystem_object(path, path, stat))
return 0;
return 2;
}

auto flags = Core::DirIterator::SkipDots;
if (flag_show_dotfiles)
flags = Core::DirIterator::Flags::NoFlags;
if (flag_show_almost_all_dotfiles)
flags = Core::DirIterator::SkipParentAndBaseDir;

Core::DirIterator di(path, flags);

if (di.has_error()) {
if (di.error() == ENOTDIR) {
struct stat stat;
Expand Down Expand Up @@ -345,18 +366,6 @@ static int do_file_system_object_long(const char* path)
metadata.name = di.next_path();
ASSERT(!metadata.name.is_empty());

if (metadata.name[0] == '.') {
if (!flag_show_dotfiles)
continue;
if (flag_show_almost_all_dotfiles) {
// skip '.' and '..' directories
if (metadata.name.length() == 1)
continue;
if (metadata.name.length() == 2 && metadata.name[1] == '.')
continue;
}
}

if (metadata.name.ends_with('~') && flag_ignore_backups && metadata.name != path)
continue;

Expand Down Expand Up @@ -411,7 +420,20 @@ static bool print_filesystem_object_short(const char* path, const char* name, si

int do_file_system_object_short(const char* path)
{
Core::DirIterator di(path, !flag_show_dotfiles ? Core::DirIterator::SkipDots : Core::DirIterator::Flags::NoFlags);
if (flag_list_directories_only) {
size_t nprinted = 0;
if (print_filesystem_object_short(path, path, &nprinted))
return 0;
return 2;
}

auto flags = Core::DirIterator::SkipDots;
if (flag_show_dotfiles)
flags = Core::DirIterator::Flags::NoFlags;
if (flag_show_almost_all_dotfiles)
flags = Core::DirIterator::SkipParentAndBaseDir;

Core::DirIterator di(path, flags);
if (di.has_error()) {
if (di.error() == ENOTDIR) {
size_t nprinted = 0;
Expand All @@ -430,18 +452,6 @@ int do_file_system_object_short(const char* path)
while (di.has_next()) {
String name = di.next_path();

if (name[0] == '.') {
if (!flag_show_dotfiles)
continue;
if (flag_show_almost_all_dotfiles) {
// skip '.' and '..' directories
if (name.length() == 1)
continue;
if (name.length() == 2 && name[1] == '.')
continue;
}
}

if (name.ends_with('~') && flag_ignore_backups && name != path)
continue;

Expand Down

0 comments on commit 28abfd6

Please sign in to comment.