mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 12:17:35 +00:00
Kernel+Userland: Add the rename() syscall along with a basic /bin/mv.
This commit is contained in:
parent
71b6436552
commit
37ae00a4dd
11 changed files with 99 additions and 2 deletions
|
@ -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);
|
||||
|
|
|
@ -75,6 +75,7 @@ public:
|
|||
KResult access(const String& path, int mode, Inode& base);
|
||||
KResult stat(const String& path, int options, Inode& base, struct stat&);
|
||||
KResult utime(const String& path, Inode& base, time_t atime, time_t mtime);
|
||||
KResult rename(const String& oldpath, const String& newpath, Inode& base);
|
||||
KResultOr<Retained<Inode>> open_directory(const String& path, Inode& base);
|
||||
|
||||
void register_device(Device&);
|
||||
|
|
|
@ -2445,3 +2445,12 @@ int Process::sys$donate(int tid)
|
|||
Scheduler::donate_to(beneficiary, "sys$donate");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Process::sys$rename(const char* oldpath, const char* newpath)
|
||||
{
|
||||
if (!validate_read_str(oldpath))
|
||||
return -EFAULT;
|
||||
if (!validate_read_str(newpath))
|
||||
return -EFAULT;
|
||||
return VFS::the().rename(String(oldpath), String(newpath), cwd_inode());
|
||||
}
|
||||
|
|
|
@ -180,6 +180,7 @@ public:
|
|||
int sys$setsockopt(const Syscall::SC_setsockopt_params*);
|
||||
int sys$restore_signal_mask(dword mask);
|
||||
int sys$create_thread(int(*)(void*), void*);
|
||||
int sys$rename(const char* oldpath, const char* newpath);
|
||||
|
||||
int sys$create_shared_buffer(pid_t peer_pid, int, void** buffer);
|
||||
void* sys$get_shared_buffer(int shared_buffer_id);
|
||||
|
|
|
@ -241,6 +241,8 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2,
|
|||
return current->process().sys$setsockopt((const SC_setsockopt_params*)arg1);
|
||||
case Syscall::SC_create_thread:
|
||||
return current->process().sys$create_thread((int(*)(void*))arg1, (void*)arg2);
|
||||
case Syscall::SC_rename:
|
||||
return current->process().sys$rename((const char*)arg1, (const char*)arg2);
|
||||
default:
|
||||
kprintf("<%u> int0x82: Unknown function %u requested {%x, %x, %x}\n", current->process().pid(), function, arg1, arg2, arg3);
|
||||
break;
|
||||
|
|
|
@ -95,6 +95,7 @@
|
|||
__ENUMERATE_SYSCALL(create_thread) \
|
||||
__ENUMERATE_SYSCALL(gettid) \
|
||||
__ENUMERATE_SYSCALL(donate) \
|
||||
__ENUMERATE_SYSCALL(rename) \
|
||||
|
||||
|
||||
namespace Syscall {
|
||||
|
|
|
@ -79,6 +79,7 @@ cp -v ../Userland/uc mnt/bin/uc
|
|||
cp -v ../Userland/tc mnt/bin/tc
|
||||
cp -v ../Userland/host mnt/bin/host
|
||||
cp -v ../Userland/qs mnt/bin/qs
|
||||
cp -v ../Userland/mv mnt/bin/mv
|
||||
chmod 4755 mnt/bin/su
|
||||
cp -v ../Applications/Terminal/Terminal mnt/bin/Terminal
|
||||
cp -v ../Applications/FontEditor/FontEditor mnt/bin/FontEditor
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue