libos: Add FileSystem::stat()
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
64d0f30bd9
commit
300d68088b
68
apps/ls.cpp
68
apps/ls.cpp
@ -1,10 +1,59 @@
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <os/ArgumentParser.h>
|
||||
#include <os/Directory.h>
|
||||
#include <os/File.h>
|
||||
#include <os/FileSystem.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
|
||||
struct UsernameCache
|
||||
{
|
||||
uid_t uid;
|
||||
String name;
|
||||
};
|
||||
|
||||
struct GroupCache
|
||||
{
|
||||
gid_t gid;
|
||||
String name;
|
||||
};
|
||||
|
||||
Vector<UsernameCache> g_user_cache;
|
||||
Vector<GroupCache> g_group_cache;
|
||||
|
||||
Result<void> find_user_and_group(struct stat& st, StringView& owner, StringView& group)
|
||||
{
|
||||
for (const auto& user : g_user_cache)
|
||||
{
|
||||
if (user.uid == st.st_uid) owner = user.name.view();
|
||||
}
|
||||
if (owner.is_empty())
|
||||
{
|
||||
auto* pw = getpwuid(st.st_uid);
|
||||
if (!pw) owner = "???";
|
||||
else
|
||||
owner = pw->pw_name;
|
||||
|
||||
auto name = TRY(String::from_string_view(owner));
|
||||
TRY(g_user_cache.try_append({ st.st_uid, move(name) }));
|
||||
}
|
||||
|
||||
for (const auto& grp : g_group_cache)
|
||||
{
|
||||
if (grp.gid == st.st_gid) group = grp.name.view();
|
||||
}
|
||||
if (group.is_empty())
|
||||
{
|
||||
auto* grp = getgrgid(st.st_gid);
|
||||
if (!grp) group = "???";
|
||||
else
|
||||
group = grp->gr_name;
|
||||
|
||||
auto name = TRY(String::from_string_view(group));
|
||||
TRY(g_group_cache.try_append({ st.st_gid, move(name) }));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<int> luna_main(int argc, char** argv)
|
||||
{
|
||||
@ -56,13 +105,14 @@ Result<int> luna_main(int argc, char** argv)
|
||||
for (const auto& file : files)
|
||||
{
|
||||
struct stat st;
|
||||
if (fstatat(dirfd, file.chars(), &st, 0) < 0)
|
||||
{
|
||||
perror(file.chars());
|
||||
return 1;
|
||||
}
|
||||
TRY(os::FileSystem::stat({ dirfd, file.view() }, st));
|
||||
|
||||
os::println("%6o %u %4u %4u %10lu %s", st.st_mode, st.st_nlink, st.st_uid, st.st_gid, st.st_size,
|
||||
StringView owner;
|
||||
StringView group;
|
||||
|
||||
TRY(find_user_and_group(st, owner, group));
|
||||
|
||||
os::println("%6o %u %4s %4s %10lu %s", st.st_mode, st.st_nlink, owner.chars(), group.chars(), st.st_size,
|
||||
file.chars());
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <os/ArgumentParser.h>
|
||||
#include <os/FileSystem.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@ -24,11 +25,7 @@ Result<int> luna_main(int argc, char** argv)
|
||||
parser.parse(argc, argv);
|
||||
|
||||
struct stat st;
|
||||
if (stat(path.chars(), &st) < 0)
|
||||
{
|
||||
perror("stat");
|
||||
return 1;
|
||||
}
|
||||
TRY(os::FileSystem::stat(path, st));
|
||||
|
||||
printf(" File: %s\n", path.chars());
|
||||
printf(" Size: %zu (%s)\n", st.st_size, file_type(st.st_mode));
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <bits/struct_stat.h>
|
||||
#include <luna/Result.h>
|
||||
#include <luna/StringView.h>
|
||||
#include <os/Path.h>
|
||||
@ -12,6 +13,8 @@ namespace os
|
||||
|
||||
bool is_directory(const Path& path);
|
||||
|
||||
Result<void> stat(const Path& path, struct stat& st);
|
||||
|
||||
Result<void> create_directory(StringView path, mode_t mode);
|
||||
|
||||
Result<void> remove(const Path& path);
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <bits/modes.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@ -6,7 +7,6 @@
|
||||
#include <os/FileSystem.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -16,7 +16,7 @@ namespace os::FileSystem
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (fstatat(path.dirfd(), path.name().chars(), &st, path.is_empty_path()) < 0) return false;
|
||||
if (stat(path, st).has_error()) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -25,11 +25,19 @@ namespace os::FileSystem
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (fstatat(path.dirfd(), path.name().chars(), &st, path.is_empty_path()) < 0) return false;
|
||||
if (stat(path, st).has_error()) return false;
|
||||
|
||||
return S_ISDIR(st.st_mode);
|
||||
}
|
||||
|
||||
Result<void> stat(const Path& path, struct stat& st)
|
||||
{
|
||||
long rc =
|
||||
syscall(SYS_fstatat, path.dirfd(), path.name().chars(), &st, path.is_empty_path() ? AT_EMPTY_PATH : 0);
|
||||
|
||||
return Result<void>::from_syscall(rc);
|
||||
}
|
||||
|
||||
Result<void> create_directory(StringView path, mode_t mode)
|
||||
{
|
||||
long rc = syscall(SYS_mkdir, path.chars(), mode);
|
||||
|
Loading…
Reference in New Issue
Block a user