summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-06-01 20:31:36 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-06-01 20:31:36 +0200
commit93d3d1ede148156a2f3eedae45a4642dd27520a5 (patch)
tree1b21d59fa4419eb17966b94c8b9358defa882252 /Kernel
parent51581c21fca245be7677d61282fe6fc7b6e69ca1 (diff)
downloadserenity-93d3d1ede148156a2f3eedae45a4642dd27520a5.zip
Kernel: Add fchown() syscall.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/FileSystem/FileDescriptor.cpp7
-rw-r--r--Kernel/FileSystem/FileDescriptor.h2
-rw-r--r--Kernel/Process.cpp8
-rw-r--r--Kernel/Process.h1
-rw-r--r--Kernel/Syscall.cpp2
-rw-r--r--Kernel/Syscall.h5
6 files changed, 23 insertions, 2 deletions
diff --git a/Kernel/FileSystem/FileDescriptor.cpp b/Kernel/FileSystem/FileDescriptor.cpp
index f7e7a36027..0fb1f71b9f 100644
--- a/Kernel/FileSystem/FileDescriptor.cpp
+++ b/Kernel/FileSystem/FileDescriptor.cpp
@@ -324,3 +324,10 @@ void FileDescriptor::set_file_flags(dword flags)
m_should_append = flags & O_APPEND;
m_file_flags = flags;
}
+
+KResult FileDescriptor::chown(uid_t uid, gid_t gid)
+{
+ if (!m_inode)
+ return KResult(-EINVAL);
+ return m_inode->chown(uid, gid);
+}
diff --git a/Kernel/FileSystem/FileDescriptor.h b/Kernel/FileSystem/FileDescriptor.h
index d95ceb6456..7d8cdf8d7d 100644
--- a/Kernel/FileSystem/FileDescriptor.h
+++ b/Kernel/FileSystem/FileDescriptor.h
@@ -101,6 +101,8 @@ public:
off_t offset() const { return m_current_offset; }
+ KResult chown(uid_t, gid_t);
+
private:
friend class VFS;
FileDescriptor(RetainPtr<File>&&, SocketRole = SocketRole::None);
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index bff015a71a..d8d7767241 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -1991,6 +1991,14 @@ int Process::sys$fchmod(int fd, mode_t mode)
return descriptor->fchmod(mode);
}
+int Process::sys$fchown(int fd, uid_t uid, gid_t gid)
+{
+ auto* descriptor = file_descriptor(fd);
+ if (!descriptor)
+ return -EBADF;
+ return descriptor->chown(uid, gid);
+}
+
int Process::sys$chown(const char* pathname, uid_t uid, gid_t gid)
{
if (!validate_read_str(pathname))
diff --git a/Kernel/Process.h b/Kernel/Process.h
index 6e1c30e723..afe621aa73 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -177,6 +177,7 @@ public:
int sys$chmod(const char* pathname, mode_t);
int sys$fchmod(int fd, mode_t);
int sys$chown(const char* pathname, uid_t, gid_t);
+ int sys$fchown(int fd, uid_t, gid_t);
int sys$socket(int domain, int type, int protocol);
int sys$bind(int sockfd, const sockaddr* addr, socklen_t);
int sys$listen(int sockfd, int backlog);
diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp
index 49ade71a3c..9d11d369da 100644
--- a/Kernel/Syscall.cpp
+++ b/Kernel/Syscall.cpp
@@ -242,6 +242,8 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2,
return current->process().sys$release_shared_buffer((int)arg1);
case Syscall::SC_chown:
return current->process().sys$chown((const char*)arg1, (uid_t)arg2, (gid_t)arg3);
+ case Syscall::SC_fchown:
+ return current->process().sys$fchown((int)arg1, (uid_t)arg2, (gid_t)arg3);
case Syscall::SC_restore_signal_mask:
return current->process().sys$restore_signal_mask((dword)arg1);
case Syscall::SC_seal_shared_buffer:
diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h
index 2428a74cec..147abcb0e8 100644
--- a/Kernel/Syscall.h
+++ b/Kernel/Syscall.h
@@ -106,8 +106,9 @@
__ENUMERATE_SYSCALL(beep) \
__ENUMERATE_SYSCALL(getsockname) \
__ENUMERATE_SYSCALL(getpeername) \
- __ENUMERATE_SYSCALL(sched_setparam) \
- __ENUMERATE_SYSCALL(sched_getparam)
+ __ENUMERATE_SYSCALL(sched_setparam) \
+ __ENUMERATE_SYSCALL(sched_getparam) \
+ __ENUMERATE_SYSCALL(fchown) \
namespace Syscall {