Compare commits
No commits in common. "597aada09ee1d8cfc8676930ef167d9702e42f87" and "47d505dcbb123890a7f7fef00cb104b721682765" have entirely different histories.
597aada09e
...
47d505dcbb
@ -28,4 +28,3 @@ luna_app(mount.cpp mount)
|
||||
luna_app(umount.cpp umount)
|
||||
luna_app(ps.cpp ps)
|
||||
luna_app(time.cpp time)
|
||||
luna_app(ln.cpp ln)
|
||||
|
24
apps/ln.cpp
24
apps/ln.cpp
@ -1,24 +0,0 @@
|
||||
#include <os/ArgumentParser.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
Result<int> luna_main(int argc, char** argv)
|
||||
{
|
||||
StringView target;
|
||||
StringView link;
|
||||
|
||||
os::ArgumentParser parser;
|
||||
parser.add_description("Create symbolic links.");
|
||||
parser.add_system_program_info("ln"_sv);
|
||||
parser.add_positional_argument(target, "target", true);
|
||||
parser.add_positional_argument(link, "linkpath", true);
|
||||
parser.parse(argc, argv);
|
||||
|
||||
if (symlink(target.chars(), link.chars()) < 0)
|
||||
{
|
||||
perror("ln");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -64,7 +64,6 @@ Result<int> 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);
|
||||
@ -76,15 +75,13 @@ Result<int> 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<String> files;
|
||||
int dirfd = AT_FDCWD;
|
||||
SharedPtr<os::Directory> dir;
|
||||
|
||||
if (os::FileSystem::is_directory(pathname, follow_symlink_args))
|
||||
if (os::FileSystem::is_directory(pathname))
|
||||
{
|
||||
dir = TRY(os::Directory::open(pathname));
|
||||
dirfd = dir->fd();
|
||||
@ -96,7 +93,7 @@ Result<int> luna_main(int argc, char** argv)
|
||||
|
||||
files = TRY(dir->list(filter));
|
||||
}
|
||||
else if (os::FileSystem::exists(pathname, follow_symlink_args))
|
||||
else if (os::FileSystem::exists(pathname))
|
||||
{
|
||||
auto str = TRY(String::from_string_view(pathname));
|
||||
TRY(files.try_append(move(str)));
|
||||
@ -114,7 +111,7 @@ Result<int> luna_main(int argc, char** argv)
|
||||
for (const auto& file : files)
|
||||
{
|
||||
struct stat st;
|
||||
TRY(os::FileSystem::stat({ dirfd, file.view() }, st, false));
|
||||
TRY(os::FileSystem::stat({ dirfd, file.view() }, st));
|
||||
|
||||
StringView owner;
|
||||
StringView group;
|
||||
|
@ -10,7 +10,6 @@ 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";
|
||||
}
|
||||
}
|
||||
@ -18,17 +17,15 @@ static const char* file_type(mode_t mode)
|
||||
Result<int> 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, follow_symlinks));
|
||||
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));
|
||||
|
@ -15,60 +15,28 @@ namespace VFS
|
||||
return *root_fs->root_inode();
|
||||
}
|
||||
|
||||
static constexpr int MAX_SYMLINKS = 8;
|
||||
|
||||
Result<SharedPtr<Inode>> resolve_path_impl(const char* path, Credentials auth, SharedPtr<Inode> current_inode,
|
||||
bool follow_last_symlink, int& symlinks_followed)
|
||||
Result<SharedPtr<Inode>> resolve_path(const char* path, Credentials auth, SharedPtr<Inode> working_directory)
|
||||
{
|
||||
if (symlinks_followed >= MAX_SYMLINKS) return err(ELOOP);
|
||||
|
||||
if (*path == '\0') return err(ENOENT);
|
||||
|
||||
auto parser = TRY(PathParser::create(path));
|
||||
|
||||
SharedPtr<Inode> parent_inode = current_inode;
|
||||
SharedPtr<Inode> current_inode;
|
||||
|
||||
if (parser.is_absolute() || !working_directory) current_inode = root_fs->root_inode();
|
||||
else
|
||||
current_inode = working_directory;
|
||||
|
||||
const char* section;
|
||||
while (parser.next().try_set_value(section))
|
||||
{
|
||||
if (!can_execute(current_inode, auth)) return err(EACCES);
|
||||
current_inode = TRY(current_inode->find(section));
|
||||
|
||||
if (current_inode->type() == VFS::InodeType::Symlink && (follow_last_symlink || parser.has_next()))
|
||||
{
|
||||
auto link = TRY(current_inode->readlink());
|
||||
|
||||
SharedPtr<VFS::Inode> symlink_root;
|
||||
|
||||
if (PathParser::is_absolute(link.chars())) symlink_root = root_fs->root_inode();
|
||||
else
|
||||
symlink_root = parent_inode;
|
||||
|
||||
symlinks_followed++;
|
||||
current_inode = TRY(resolve_path_impl(link.chars(), auth, symlink_root, true, symlinks_followed));
|
||||
symlinks_followed--;
|
||||
}
|
||||
|
||||
parent_inode = current_inode;
|
||||
}
|
||||
|
||||
return current_inode;
|
||||
}
|
||||
|
||||
Result<SharedPtr<Inode>> resolve_path(const char* path, Credentials auth, SharedPtr<VFS::Inode> working_directory,
|
||||
bool follow_last_symlink)
|
||||
{
|
||||
SharedPtr<Inode> current_inode;
|
||||
|
||||
if (PathParser::is_absolute(path) || !working_directory) current_inode = root_fs->root_inode();
|
||||
else
|
||||
current_inode = working_directory;
|
||||
|
||||
int symlinks_followed = 0;
|
||||
|
||||
return resolve_path_impl(path, auth, current_inode, follow_last_symlink, symlinks_followed);
|
||||
}
|
||||
|
||||
Result<SharedPtr<Inode>> create_directory(const char* path, Credentials auth, SharedPtr<Inode> working_directory)
|
||||
{
|
||||
auto parser = TRY(PathParser::create(path));
|
||||
|
@ -12,8 +12,7 @@ namespace VFS
|
||||
{
|
||||
RegularFile,
|
||||
Directory,
|
||||
Device,
|
||||
Symlink
|
||||
Device
|
||||
};
|
||||
|
||||
class Inode;
|
||||
@ -29,8 +28,6 @@ namespace VFS
|
||||
|
||||
virtual Result<SharedPtr<Inode>> create_device_inode(u32 major, u32 minor) = 0;
|
||||
|
||||
virtual Result<SharedPtr<Inode>> create_symlink_inode(StringView link) = 0;
|
||||
|
||||
virtual Result<void> set_mount_dir(SharedPtr<Inode> parent) = 0;
|
||||
|
||||
virtual u64 handles() const
|
||||
@ -95,12 +92,6 @@ namespace VFS
|
||||
|
||||
virtual bool blocking() const = 0;
|
||||
|
||||
// Symlink-specific methods
|
||||
virtual Result<StringView> readlink()
|
||||
{
|
||||
return StringView {};
|
||||
}
|
||||
|
||||
// Metadata accessors
|
||||
virtual usize size() const = 0;
|
||||
|
||||
@ -259,8 +250,7 @@ namespace VFS
|
||||
};
|
||||
|
||||
Result<SharedPtr<Inode>> resolve_path(const char* path, Credentials auth,
|
||||
SharedPtr<VFS::Inode> working_directory = {},
|
||||
bool follow_last_symlink = true);
|
||||
SharedPtr<VFS::Inode> working_directory = {});
|
||||
|
||||
Result<SharedPtr<Inode>> create_directory(const char* path, Credentials auth,
|
||||
SharedPtr<VFS::Inode> working_directory = {});
|
||||
|
@ -24,15 +24,6 @@ namespace TmpFS
|
||||
return (SharedPtr<VFS::Inode>)inode;
|
||||
}
|
||||
|
||||
Result<SharedPtr<VFS::Inode>> FileSystem::create_symlink_inode(StringView link)
|
||||
{
|
||||
SharedPtr<SymlinkInode> inode = TRY(make_shared<SymlinkInode>());
|
||||
inode->set_fs(*this, {});
|
||||
TRY(inode->set_link(link, {}));
|
||||
inode->set_inode_number(m_next_inode_number++, {});
|
||||
return (SharedPtr<VFS::Inode>)inode;
|
||||
}
|
||||
|
||||
Result<SharedPtr<VFS::Inode>> FileSystem::create_dir_inode(SharedPtr<VFS::Inode> parent)
|
||||
{
|
||||
SharedPtr<DirInode> inode = TRY(make_shared<DirInode>());
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include <luna/Badge.h>
|
||||
#include <luna/Buffer.h>
|
||||
#include <luna/StaticString.h>
|
||||
#include <luna/String.h>
|
||||
#include <luna/Vector.h>
|
||||
|
||||
namespace TmpFS
|
||||
@ -21,7 +20,6 @@ namespace TmpFS
|
||||
Result<SharedPtr<VFS::Inode>> create_file_inode() override;
|
||||
Result<SharedPtr<VFS::Inode>> create_dir_inode(SharedPtr<VFS::Inode> parent) override;
|
||||
Result<SharedPtr<VFS::Inode>> create_device_inode(u32 major, u32 minor) override;
|
||||
Result<SharedPtr<VFS::Inode>> create_symlink_inode(StringView link) override;
|
||||
|
||||
Result<void> set_mount_dir(SharedPtr<VFS::Inode> parent) override;
|
||||
|
||||
@ -122,115 +120,6 @@ namespace TmpFS
|
||||
u32 m_nlinks { 0 };
|
||||
};
|
||||
|
||||
class SymlinkInode : public VFS::FileInode
|
||||
{
|
||||
public:
|
||||
SymlinkInode() = default;
|
||||
|
||||
VFS::InodeType type() const override
|
||||
{
|
||||
return VFS::InodeType::Symlink;
|
||||
}
|
||||
|
||||
void set_fs(FileSystem& fs, Badge<FileSystem>)
|
||||
{
|
||||
m_fs = &fs;
|
||||
}
|
||||
|
||||
void set_inode_number(usize inum, Badge<FileSystem>)
|
||||
{
|
||||
m_inode_number = inum;
|
||||
}
|
||||
|
||||
Result<void> set_link(StringView link, Badge<FileSystem>)
|
||||
{
|
||||
m_link = TRY(String::from_string_view(link));
|
||||
return {};
|
||||
}
|
||||
|
||||
VFS::FileSystem* fs() const override
|
||||
{
|
||||
return m_fs;
|
||||
}
|
||||
|
||||
usize inode_number() const override
|
||||
{
|
||||
return m_inode_number;
|
||||
}
|
||||
|
||||
Result<usize> read(u8*, usize, usize) const override
|
||||
{
|
||||
return err(ENOTSUP);
|
||||
}
|
||||
|
||||
Result<usize> write(const u8*, usize, usize) override
|
||||
{
|
||||
return err(ENOTSUP);
|
||||
}
|
||||
|
||||
Result<void> truncate(usize) override
|
||||
{
|
||||
return err(ENOTSUP);
|
||||
}
|
||||
|
||||
usize size() const override
|
||||
{
|
||||
return m_link.length();
|
||||
}
|
||||
|
||||
mode_t mode() const override
|
||||
{
|
||||
return 0777;
|
||||
}
|
||||
|
||||
u32 uid() const override
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
|
||||
u32 gid() const override
|
||||
{
|
||||
return m_gid;
|
||||
}
|
||||
|
||||
Result<void> chmod(mode_t) override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<void> chown(u32 uid, u32 gid) override
|
||||
{
|
||||
m_uid = uid;
|
||||
m_gid = gid;
|
||||
return {};
|
||||
}
|
||||
|
||||
void did_link() override
|
||||
{
|
||||
m_nlinks++;
|
||||
}
|
||||
|
||||
void did_unlink() override
|
||||
{
|
||||
m_nlinks--;
|
||||
}
|
||||
|
||||
Result<StringView> readlink() override
|
||||
{
|
||||
return m_link.view();
|
||||
}
|
||||
|
||||
virtual ~SymlinkInode() = default;
|
||||
|
||||
private:
|
||||
VFS::FileSystem* m_fs;
|
||||
String m_link;
|
||||
usize m_inode_number;
|
||||
u32 m_uid { 0 };
|
||||
u32 m_gid { 0 };
|
||||
u32 m_nlinks { 0 };
|
||||
};
|
||||
|
||||
class DeviceInode : public VFS::DeviceInode
|
||||
{
|
||||
public:
|
||||
|
@ -104,7 +104,7 @@ Result<u64> sys_fchmodat(Registers*, SyscallArgs args)
|
||||
|
||||
auto* current = Scheduler::current();
|
||||
|
||||
auto inode = TRY(current->resolve_atfile(dirfd, path, flags & AT_EMPTY_PATH, !(flags & AT_SYMLINK_NOFOLLOW)));
|
||||
auto inode = TRY(current->resolve_atfile(dirfd, path, flags & AT_EMPTY_PATH));
|
||||
|
||||
if (current->auth.euid != 0 && current->auth.euid != inode->uid()) return err(EPERM);
|
||||
|
||||
@ -123,7 +123,7 @@ Result<u64> sys_fchownat(Registers*, SyscallArgs args)
|
||||
|
||||
auto* current = Scheduler::current();
|
||||
|
||||
auto inode = TRY(current->resolve_atfile(dirfd, path, flags & AT_EMPTY_PATH, !(flags & AT_SYMLINK_NOFOLLOW)));
|
||||
auto inode = TRY(current->resolve_atfile(dirfd, path, flags & AT_EMPTY_PATH));
|
||||
|
||||
if (current->auth.euid != 0) return err(EPERM);
|
||||
|
||||
|
@ -21,7 +21,7 @@ Result<u64> sys_unlinkat(Registers*, SyscallArgs args)
|
||||
|
||||
kinfoln("unlinkat: remove %s from directory %s, dirfd is %d", basename.chars(), dirname.chars(), dirfd);
|
||||
|
||||
auto inode = TRY(current->resolve_atfile(dirfd, dirname, false, false));
|
||||
auto inode = TRY(current->resolve_atfile(dirfd, dirname, false));
|
||||
if (!VFS::can_write(inode, current->auth)) return err(EACCES);
|
||||
|
||||
if (flags > 0)
|
||||
@ -34,31 +34,3 @@ Result<u64> sys_unlinkat(Registers*, SyscallArgs args)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result<u64> sys_symlinkat(Registers*, SyscallArgs args)
|
||||
{
|
||||
auto target = TRY(MemoryManager::strdup_from_user(args[0]));
|
||||
int dirfd = (int)args[1];
|
||||
auto linkpath = TRY(MemoryManager::strdup_from_user(args[2]));
|
||||
|
||||
if (target.is_empty()) return err(ENOENT);
|
||||
|
||||
auto* current = Scheduler::current();
|
||||
|
||||
auto parser = TRY(PathParser::create(linkpath.chars()));
|
||||
auto parent = TRY(parser.dirname());
|
||||
|
||||
auto parent_inode = TRY(current->resolve_atfile(dirfd, parent, false, true));
|
||||
|
||||
if (!VFS::can_write(parent_inode, current->auth)) return err(EACCES);
|
||||
|
||||
auto child_name = TRY(parser.basename());
|
||||
|
||||
TRY(VFS::validate_filename(child_name.view()));
|
||||
|
||||
auto inode = TRY(parent_inode->fs()->create_symlink_inode(target.view()));
|
||||
TRY(inode->chown(current->auth.euid, current->auth.egid));
|
||||
TRY(parent_inode->add_entry(inode, child_name.chars()));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -31,8 +31,7 @@ Result<u64> sys_openat(Registers*, SyscallArgs args)
|
||||
|
||||
int error;
|
||||
SharedPtr<VFS::Inode> parent_inode;
|
||||
bool ok = current->resolve_atfile(dirfd, path, false, !(flags & O_NOFOLLOW), &parent_inode)
|
||||
.try_set_value_or_error(inode, error);
|
||||
bool ok = current->resolve_atfile(dirfd, path, false, &parent_inode).try_set_value_or_error(inode, error);
|
||||
if (!ok)
|
||||
{
|
||||
if (error == ENOENT && (flags & O_CREAT) && !path.is_empty())
|
||||
@ -52,9 +51,6 @@ Result<u64> sys_openat(Registers*, SyscallArgs args)
|
||||
if ((flags & O_WRONLY) && !VFS::can_write(inode, current->auth)) return err(EACCES);
|
||||
}
|
||||
|
||||
// This should only be possible if O_NOFOLLOW was in flags.
|
||||
if (inode->type() == VFS::InodeType::Symlink) return err(ELOOP);
|
||||
|
||||
if (flags & O_TMPFILE)
|
||||
{
|
||||
if (inode->type() != VFS::InodeType::Directory) return err(EINVAL);
|
||||
|
@ -14,7 +14,6 @@ static mode_t make_mode(mode_t mode, VFS::InodeType type)
|
||||
case VFS::InodeType::RegularFile: result |= S_IFREG; break;
|
||||
case VFS::InodeType::Directory: result |= S_IFDIR; break;
|
||||
case VFS::InodeType::Device: result |= S_IFCHR; break;
|
||||
case VFS::InodeType::Symlink: result |= S_IFLNK; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
@ -30,7 +29,7 @@ Result<u64> sys_fstatat(Registers*, SyscallArgs args)
|
||||
|
||||
Thread* current = Scheduler::current();
|
||||
|
||||
auto inode = TRY(current->resolve_atfile(dirfd, path, flags & AT_EMPTY_PATH, !(flags & AT_SYMLINK_NOFOLLOW)));
|
||||
auto inode = TRY(current->resolve_atfile(dirfd, path, flags & AT_EMPTY_PATH));
|
||||
|
||||
stat kstat;
|
||||
|
||||
|
@ -49,15 +49,13 @@ Result<FileDescriptor*> Thread::resolve_fd(int fd)
|
||||
}
|
||||
|
||||
Result<SharedPtr<VFS::Inode>> Thread::resolve_atfile(int dirfd, const String& path, bool allow_empty_path,
|
||||
bool follow_last_symlink, SharedPtr<VFS::Inode>* parent_inode)
|
||||
SharedPtr<VFS::Inode>* parent_inode)
|
||||
{
|
||||
if (parent_inode) *parent_inode = this->current_directory;
|
||||
|
||||
if (PathParser::is_absolute(path.view()))
|
||||
return VFS::resolve_path(path.chars(), this->auth, {}, follow_last_symlink);
|
||||
if (PathParser::is_absolute(path.view())) return VFS::resolve_path(path.chars(), this->auth);
|
||||
|
||||
if (dirfd == AT_FDCWD)
|
||||
return VFS::resolve_path(path.chars(), this->auth, this->current_directory, follow_last_symlink);
|
||||
if (dirfd == AT_FDCWD) return VFS::resolve_path(path.chars(), this->auth, this->current_directory);
|
||||
|
||||
auto descriptor = TRY(resolve_fd(dirfd));
|
||||
|
||||
@ -65,7 +63,7 @@ Result<SharedPtr<VFS::Inode>> Thread::resolve_atfile(int dirfd, const String& pa
|
||||
|
||||
if (path.is_empty() && allow_empty_path) return descriptor->inode;
|
||||
|
||||
return VFS::resolve_path(path.chars(), this->auth, descriptor->inode, follow_last_symlink);
|
||||
return VFS::resolve_path(path.chars(), this->auth, descriptor->inode);
|
||||
}
|
||||
|
||||
bool FileDescriptor::should_append()
|
||||
|
@ -76,7 +76,6 @@ struct Thread : public LinkedListNode<Thread>
|
||||
Result<int> allocate_fd(int min);
|
||||
Result<FileDescriptor*> resolve_fd(int fd);
|
||||
Result<SharedPtr<VFS::Inode>> resolve_atfile(int dirfd, const String& path, bool allow_empty_path,
|
||||
bool follow_last_symlink,
|
||||
SharedPtr<VFS::Inode>* parent_inode = nullptr);
|
||||
|
||||
FPData fp_data;
|
||||
|
@ -6,7 +6,6 @@
|
||||
#define AT_FDCWD -100
|
||||
|
||||
#define AT_EMPTY_PATH 1
|
||||
#define AT_SYMLINK_NOFOLLOW 2
|
||||
|
||||
#define AT_REMOVEDIR 1
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
#define S_IFMT 070000
|
||||
#define S_IFREG 000000
|
||||
#define S_IFLNK 010000
|
||||
#define S_IFDIR 040000
|
||||
#define S_IFCHR 050000
|
||||
|
||||
@ -14,7 +13,6 @@
|
||||
#define S_ISREG(mode) __CHECK_TYPE(mode, S_IFREG)
|
||||
#define S_ISDIR(mode) __CHECK_TYPE(mode, S_IFDIR)
|
||||
#define S_ISCHR(mode) __CHECK_TYPE(mode, S_IFCHR)
|
||||
#define S_ISLNK(mode) __CHECK_TYPE(mode, S_IFLNK)
|
||||
|
||||
#define S_IRWXU 0700
|
||||
#define S_IRUSR 0400
|
||||
|
@ -14,7 +14,6 @@
|
||||
#define O_CLOEXEC 128
|
||||
#define O_DIRECTORY 256
|
||||
#define O_TMPFILE 512
|
||||
#define O_NOFOLLOW 1024
|
||||
|
||||
#define O_ACCMODE O_RDWR
|
||||
|
||||
|
@ -71,9 +71,6 @@ extern "C"
|
||||
/* Separate a string into several tokens. */
|
||||
char* strtok(char* str, const char* delim);
|
||||
|
||||
/* Separate a string into several tokens. */
|
||||
char* strtok_r(char* str, const char* delim, char** savep);
|
||||
|
||||
/* Return a heap-allocated copy of a fixed-size string. */
|
||||
char* strndup(const char* str, size_t max);
|
||||
|
||||
|
@ -29,9 +29,6 @@ extern "C"
|
||||
|
||||
#pragma GCC pop_options
|
||||
|
||||
/* Retrieve information about a file or symbolic link. */
|
||||
int lstat(const char* path, struct stat* st);
|
||||
|
||||
/* Retrieve information about a file. */
|
||||
int fstat(int fd, struct stat* st);
|
||||
|
||||
|
@ -133,12 +133,6 @@ extern "C"
|
||||
/* Create a pipe for inter-process communication. */
|
||||
int pipe(int pfds[2]);
|
||||
|
||||
/* Create a symbolic link. */
|
||||
int symlink(const char* target, const char* linkpath);
|
||||
|
||||
/* Create a symbolic link relative to a file descriptor. */
|
||||
int symlinkat(const char* target, int dirfd, const char* linkpath);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -30,12 +30,6 @@ extern "C"
|
||||
__errno_return(rc, int);
|
||||
}
|
||||
|
||||
int lstat(const char* path, struct stat* st)
|
||||
{
|
||||
long rc = syscall(SYS_fstatat, AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW);
|
||||
__errno_return(rc, int);
|
||||
}
|
||||
|
||||
int fstat(int fd, struct stat* st)
|
||||
{
|
||||
long rc = syscall(SYS_fstatat, fd, "", st, AT_EMPTY_PATH);
|
||||
|
@ -406,16 +406,4 @@ extern "C"
|
||||
long rc = syscall(SYS_pipe, (int*)pfds);
|
||||
__errno_return(rc, int);
|
||||
}
|
||||
|
||||
int symlink(const char* target, const char* linkpath)
|
||||
{
|
||||
long rc = syscall(SYS_symlinkat, target, AT_FDCWD, linkpath);
|
||||
__errno_return(rc, int);
|
||||
}
|
||||
|
||||
int symlinkat(const char* target, int dirfd, const char* linkpath)
|
||||
{
|
||||
long rc = syscall(SYS_symlinkat, target, dirfd, linkpath);
|
||||
__errno_return(rc, int);
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ extern "C"
|
||||
usize strcspn(const char* str, const char* reject);
|
||||
|
||||
char* strtok(char* str, const char* delim);
|
||||
char* strtok_r(char* str, const char* delim, char** savep);
|
||||
|
||||
usize wcslen(const wchar_t* str);
|
||||
int wcscmp(const wchar_t* a, const wchar_t* b);
|
||||
|
@ -3,11 +3,6 @@
|
||||
#include <luna/Heap.h>
|
||||
#include <luna/String.h>
|
||||
|
||||
static inline bool is_not_delim(char c)
|
||||
{
|
||||
return c && c != '/';
|
||||
}
|
||||
|
||||
class PathParser
|
||||
{
|
||||
public:
|
||||
@ -32,11 +27,6 @@ class PathParser
|
||||
return is_absolute(StringView { m_original });
|
||||
}
|
||||
|
||||
bool has_next() const
|
||||
{
|
||||
return m_already_called_next ? (bool)m_strtok_saved_state : is_not_delim(*m_copy);
|
||||
}
|
||||
|
||||
Result<String> basename();
|
||||
Result<String> dirname();
|
||||
|
||||
@ -48,5 +38,4 @@ class PathParser
|
||||
const char* m_original { nullptr };
|
||||
char* m_copy { nullptr };
|
||||
bool m_already_called_next { false };
|
||||
char* m_strtok_saved_state { nullptr };
|
||||
};
|
||||
|
@ -5,7 +5,7 @@
|
||||
_e(lseek) _e(mkdir) _e(execve) _e(fork) _e(waitpid) _e(getppid) _e(fcntl) _e(getdents) _e(getuid) _e(geteuid) \
|
||||
_e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(fchmodat) _e(fchownat) _e(ioctl) \
|
||||
_e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe) _e(mount) \
|
||||
_e(umount) _e(pstat) _e(getrusage) _e(symlinkat)
|
||||
_e(umount) _e(pstat) _e(getrusage)
|
||||
|
||||
enum Syscalls
|
||||
{
|
||||
|
@ -219,9 +219,9 @@ extern "C"
|
||||
return (usize)(s - str);
|
||||
}
|
||||
|
||||
char* strtok_r(char* str, const char* delim, char** savep)
|
||||
char* strtok(char* str, const char* delim)
|
||||
{
|
||||
auto& s = *savep;
|
||||
static char* s = nullptr;
|
||||
if (str) s = str;
|
||||
if (!s) return nullptr;
|
||||
|
||||
@ -248,12 +248,6 @@ extern "C"
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char* strtok(char* str, const char* delim)
|
||||
{
|
||||
static char* s;
|
||||
return strtok_r(str, delim, &s);
|
||||
}
|
||||
|
||||
char* strpbrk(const char* s, const char* accept)
|
||||
{
|
||||
usize index = strcspn(s, accept);
|
||||
|
@ -27,7 +27,7 @@ PathParser::~PathParser()
|
||||
|
||||
Option<const char*> PathParser::next()
|
||||
{
|
||||
char* result = strtok_r(m_already_called_next ? nullptr : m_copy, "/", &m_strtok_saved_state);
|
||||
char* result = strtok(m_already_called_next ? nullptr : m_copy, "/");
|
||||
m_already_called_next = true;
|
||||
|
||||
if (!result) return {};
|
||||
|
@ -9,11 +9,11 @@ namespace os
|
||||
{
|
||||
namespace FileSystem
|
||||
{
|
||||
bool exists(const Path& path, bool follow_symlinks = true);
|
||||
bool exists(const Path& path);
|
||||
|
||||
bool is_directory(const Path& path, bool follow_symlinks = false);
|
||||
bool is_directory(const Path& path);
|
||||
|
||||
Result<void> stat(const Path& path, struct stat& st, bool follow_symlinks = true);
|
||||
Result<void> stat(const Path& path, struct stat& st);
|
||||
|
||||
Result<void> create_directory(StringView path, mode_t mode);
|
||||
|
||||
|
@ -12,29 +12,28 @@
|
||||
|
||||
namespace os::FileSystem
|
||||
{
|
||||
bool exists(const Path& path, bool follow_symlinks)
|
||||
bool exists(const Path& path)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (stat(path, st, follow_symlinks).has_error()) return false;
|
||||
if (stat(path, st).has_error()) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_directory(const Path& path, bool follow_symlinks)
|
||||
bool is_directory(const Path& path)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (stat(path, st, follow_symlinks).has_error()) 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, bool follow_symlinks)
|
||||
Result<void> stat(const Path& path, struct stat& st)
|
||||
{
|
||||
long rc =
|
||||
syscall(SYS_fstatat, path.dirfd(), path.name().chars(), &st,
|
||||
(int)((path.is_empty_path() ? AT_EMPTY_PATH : 0) | (follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW)));
|
||||
syscall(SYS_fstatat, path.dirfd(), path.name().chars(), &st, path.is_empty_path() ? AT_EMPTY_PATH : 0);
|
||||
|
||||
return Result<void>::from_syscall(rc);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user