ls+stat: Handle symbolic links properly
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
4ec1af5e51
commit
597aada09e
@ -64,6 +64,7 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
bool long_list { false };
|
bool long_list { false };
|
||||||
bool human_readable { false };
|
bool human_readable { false };
|
||||||
bool si { false };
|
bool si { false };
|
||||||
|
bool follow_symlink_args { false };
|
||||||
|
|
||||||
os::ArgumentParser parser;
|
os::ArgumentParser parser;
|
||||||
parser.add_description("List files contained in a directory (defaults to '.', the current directory)"_sv);
|
parser.add_description("List files contained in a directory (defaults to '.', the current directory)"_sv);
|
||||||
@ -75,13 +76,15 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
parser.add_switch_argument(human_readable, 'h', "human-readable"_sv,
|
parser.add_switch_argument(human_readable, 'h', "human-readable"_sv,
|
||||||
"with -l, show human-readable sizes e.g. 2KiB, 6GiB"_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(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);
|
parser.parse(argc, argv);
|
||||||
|
|
||||||
Vector<String> files;
|
Vector<String> files;
|
||||||
int dirfd = AT_FDCWD;
|
int dirfd = AT_FDCWD;
|
||||||
SharedPtr<os::Directory> dir;
|
SharedPtr<os::Directory> dir;
|
||||||
|
|
||||||
if (os::FileSystem::is_directory(pathname))
|
if (os::FileSystem::is_directory(pathname, follow_symlink_args))
|
||||||
{
|
{
|
||||||
dir = TRY(os::Directory::open(pathname));
|
dir = TRY(os::Directory::open(pathname));
|
||||||
dirfd = dir->fd();
|
dirfd = dir->fd();
|
||||||
@ -93,7 +96,7 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
|
|
||||||
files = TRY(dir->list(filter));
|
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));
|
auto str = TRY(String::from_string_view(pathname));
|
||||||
TRY(files.try_append(move(str)));
|
TRY(files.try_append(move(str)));
|
||||||
@ -111,7 +114,7 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
for (const auto& file : files)
|
for (const auto& file : files)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
TRY(os::FileSystem::stat({ dirfd, file.view() }, st));
|
TRY(os::FileSystem::stat({ dirfd, file.view() }, st, false));
|
||||||
|
|
||||||
StringView owner;
|
StringView owner;
|
||||||
StringView group;
|
StringView group;
|
||||||
|
@ -10,6 +10,7 @@ static const char* file_type(mode_t mode)
|
|||||||
case S_IFREG: return "regular file";
|
case S_IFREG: return "regular file";
|
||||||
case S_IFDIR: return "directory";
|
case S_IFDIR: return "directory";
|
||||||
case S_IFCHR: return "character special device";
|
case S_IFCHR: return "character special device";
|
||||||
|
case S_IFLNK: return "symbolic link";
|
||||||
default: return "unknown file type";
|
default: return "unknown file type";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -17,15 +18,17 @@ static const char* file_type(mode_t mode)
|
|||||||
Result<int> luna_main(int argc, char** argv)
|
Result<int> luna_main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
StringView path;
|
StringView path;
|
||||||
|
bool follow_symlinks { false };
|
||||||
|
|
||||||
os::ArgumentParser parser;
|
os::ArgumentParser parser;
|
||||||
parser.add_description("Display file status.");
|
parser.add_description("Display file status.");
|
||||||
parser.add_system_program_info("stat"_sv);
|
parser.add_system_program_info("stat"_sv);
|
||||||
parser.add_positional_argument(path, "path", true);
|
parser.add_positional_argument(path, "path", true);
|
||||||
|
parser.add_switch_argument(follow_symlinks, 'L', "dereference"_sv, "follow symlinks");
|
||||||
parser.parse(argc, argv);
|
parser.parse(argc, argv);
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
TRY(os::FileSystem::stat(path, st));
|
TRY(os::FileSystem::stat(path, st, follow_symlinks));
|
||||||
|
|
||||||
printf(" File: %s\n", path.chars());
|
printf(" File: %s\n", path.chars());
|
||||||
printf(" Size: %zu (%s)\n", st.st_size, file_type(st.st_mode));
|
printf(" Size: %zu (%s)\n", st.st_size, file_type(st.st_mode));
|
||||||
|
Loading…
Reference in New Issue
Block a user