From 597aada09ee1d8cfc8676930ef167d9702e42f87 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 20 May 2023 21:48:46 +0200 Subject: [PATCH] ls+stat: Handle symbolic links properly --- apps/ls.cpp | 9 ++++++--- apps/stat.cpp | 5 ++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/ls.cpp b/apps/ls.cpp index 7dd3c4c6..ee89ca82 100644 --- a/apps/ls.cpp +++ b/apps/ls.cpp @@ -64,6 +64,7 @@ Result luna_main(int argc, char** argv) bool long_list { false }; bool human_readable { false }; bool si { false }; + bool follow_symlink_args { false }; os::ArgumentParser parser; parser.add_description("List files contained in a directory (defaults to '.', the current directory)"_sv); @@ -75,13 +76,15 @@ Result luna_main(int argc, char** argv) parser.add_switch_argument(human_readable, 'h', "human-readable"_sv, "with -l, show human-readable sizes e.g. 2KiB, 6GiB"_sv); parser.add_switch_argument(si, ' ', "si"_sv, "same as -h, but show sizes in powers of 10"_sv); + parser.add_switch_argument(follow_symlink_args, 'H', "dereference-args"_sv, + "follow symbolic links listed as arguments"_sv); parser.parse(argc, argv); Vector files; int dirfd = AT_FDCWD; SharedPtr dir; - if (os::FileSystem::is_directory(pathname)) + if (os::FileSystem::is_directory(pathname, follow_symlink_args)) { dir = TRY(os::Directory::open(pathname)); dirfd = dir->fd(); @@ -93,7 +96,7 @@ Result luna_main(int argc, char** argv) files = TRY(dir->list(filter)); } - else if (os::FileSystem::exists(pathname)) + else if (os::FileSystem::exists(pathname, follow_symlink_args)) { auto str = TRY(String::from_string_view(pathname)); TRY(files.try_append(move(str))); @@ -111,7 +114,7 @@ Result luna_main(int argc, char** argv) for (const auto& file : files) { struct stat st; - TRY(os::FileSystem::stat({ dirfd, file.view() }, st)); + TRY(os::FileSystem::stat({ dirfd, file.view() }, st, false)); StringView owner; StringView group; diff --git a/apps/stat.cpp b/apps/stat.cpp index 2c225029..ff3d905c 100644 --- a/apps/stat.cpp +++ b/apps/stat.cpp @@ -10,6 +10,7 @@ static const char* file_type(mode_t mode) case S_IFREG: return "regular file"; case S_IFDIR: return "directory"; case S_IFCHR: return "character special device"; + case S_IFLNK: return "symbolic link"; default: return "unknown file type"; } } @@ -17,15 +18,17 @@ static const char* file_type(mode_t mode) Result luna_main(int argc, char** argv) { StringView path; + bool follow_symlinks { false }; os::ArgumentParser parser; parser.add_description("Display file status."); parser.add_system_program_info("stat"_sv); parser.add_positional_argument(path, "path", true); + parser.add_switch_argument(follow_symlinks, 'L', "dereference"_sv, "follow symlinks"); parser.parse(argc, argv); struct stat st; - TRY(os::FileSystem::stat(path, st)); + TRY(os::FileSystem::stat(path, st, follow_symlinks)); printf(" File: %s\n", path.chars()); printf(" Size: %zu (%s)\n", st.st_size, file_type(st.st_mode));