Kernel+Userland: Add the rename() syscall along with a basic /bin/mv.

This commit is contained in:
Andreas Kling 2019-04-07 23:35:26 +02:00
parent 71b6436552
commit 37ae00a4dd
Notes: sideshowbarker 2024-07-19 14:47:42 +09:00
11 changed files with 99 additions and 2 deletions

View file

@ -312,6 +312,50 @@ KResult VFS::chmod(const String& path, mode_t mode, Inode& base)
return chmod(*inode, mode);
}
KResult VFS::rename(const String& old_path, const String& new_path, Inode& base)
{
RetainPtr<Inode> old_parent_inode;
auto old_inode_or_error = resolve_path_to_inode(old_path, base, &old_parent_inode);
if (old_inode_or_error.is_error())
return old_inode_or_error.error();
auto old_inode = old_inode_or_error.value();
RetainPtr<Inode> new_parent_inode;
auto new_inode_or_error = resolve_path_to_inode(new_path, base, &new_parent_inode);
if (new_inode_or_error.is_error()) {
if (new_inode_or_error.error() != -ENOENT)
return new_inode_or_error.error();
}
if (!new_parent_inode->metadata().may_write(current->process()))
return KResult(-EACCES);
if (!old_parent_inode->metadata().may_write(current->process()))
return KResult(-EACCES);
if (!new_inode_or_error.is_error()) {
auto new_inode = new_inode_or_error.value();
// FIXME: Is this really correct? Check what other systems do.
if (new_inode.ptr() == old_inode.ptr())
return KSuccess;
if (new_inode->is_directory() && !old_inode->is_directory())
return KResult(-EISDIR);
auto result = new_parent_inode->remove_child(new_parent_inode->reverse_lookup(new_inode->identifier()));
if (result.is_error())
return result;
}
auto result = new_parent_inode->add_child(old_inode->identifier(), FileSystemPath(new_path).basename(), 0 /* FIXME: file type? */);
if (result.is_error())
return result;
result = old_parent_inode->remove_child(old_parent_inode->reverse_lookup(old_inode->identifier()));
if (result.is_error())
return result;
return KSuccess;
}
KResult VFS::chown(const String& path, uid_t a_uid, gid_t a_gid, Inode& base)
{
auto inode_or_error = resolve_path_to_inode(path, base);