2023-04-12 16:11:36 +00:00
|
|
|
#include "memory/MemoryManager.h"
|
|
|
|
#include "sys/Syscall.h"
|
|
|
|
#include "thread/Scheduler.h"
|
|
|
|
#include <luna/PathParser.h>
|
|
|
|
|
2023-04-18 17:36:29 +00:00
|
|
|
Result<u64> sys_unlinkat(Registers*, SyscallArgs args)
|
2023-04-12 16:11:36 +00:00
|
|
|
{
|
2023-04-18 17:36:29 +00:00
|
|
|
int dirfd = (int)args[0];
|
|
|
|
auto path = TRY(MemoryManager::strdup_from_user(args[1]));
|
|
|
|
int flags = (int)args[2];
|
2023-04-12 16:11:36 +00:00
|
|
|
|
|
|
|
Thread* current = Scheduler::current();
|
|
|
|
|
|
|
|
PathParser parser = TRY(PathParser::create(path.chars()));
|
|
|
|
|
|
|
|
auto dirname = TRY(parser.dirname());
|
|
|
|
auto basename = TRY(parser.basename());
|
|
|
|
|
|
|
|
if (basename.view() == ".") return err(EINVAL);
|
|
|
|
|
2023-04-18 17:36:29 +00:00
|
|
|
auto inode = TRY(current->resolve_atfile(dirfd, dirname, false));
|
2023-04-12 16:11:36 +00:00
|
|
|
if (!VFS::can_write(inode, current->auth)) return err(EACCES);
|
|
|
|
|
|
|
|
if (flags > 0)
|
|
|
|
{
|
|
|
|
auto child = TRY(inode->find(basename.chars()));
|
|
|
|
if (child->type() != VFS::InodeType::Directory) return err(ENOTDIR);
|
|
|
|
}
|
|
|
|
|
|
|
|
TRY(inode->remove_entry(basename.chars()));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|