From b1d4f55e0a83461c2803f756ad99b8c9c05f4e99 Mon Sep 17 00:00:00 2001
From: 4lDO2 <4lDO2@protonmail.com>
Date: Sun, 28 May 2023 11:12:30 +0200
Subject: [PATCH] Use kopen and kdup in syscall handlers.

---
 src/scheme/mod.rs  |  6 ++++++
 src/scheme/user.rs | 12 +++---------
 src/syscall/fs.rs  | 48 +++++++++++++++++++++++++---------------------
 3 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/src/scheme/mod.rs b/src/scheme/mod.rs
index 7c6ffb05..909385d2 100644
--- a/src/scheme/mod.rs
+++ b/src/scheme/mod.rs
@@ -325,3 +325,9 @@ pub enum OpenResult {
     SchemeLocal(usize),
     External(Arc<RwLock<FileDescription>>),
 }
+
+pub fn current_caller_ctx() -> Result<CallerCtx> {
+    match crate::context::current()?.read() {
+        ref context => Ok(CallerCtx { pid: context.id.into(), uid: context.euid, gid: context.egid }),
+    }
+}
diff --git a/src/scheme/user.rs b/src/scheme/user.rs
index 266c5f64..fe76233c 100644
--- a/src/scheme/user.rs
+++ b/src/scheme/user.rs
@@ -20,7 +20,7 @@ use crate::syscall::flag::{EventFlags, EVENT_READ, O_NONBLOCK, MapFlags, PROT_RE
 use crate::syscall::number::*;
 use crate::syscall::scheme::Scheme;
 
-use super::{FileHandle, OpenResult, KernelScheme};
+use super::{FileHandle, OpenResult, KernelScheme, current_caller_ctx};
 
 pub struct UserInner {
     root_id: SchemeId,
@@ -78,14 +78,8 @@ impl UserInner {
         id
     }
 
-    fn current_caller_ctx() -> Result<CallerCtx> {
-        match context::current()?.read() {
-            ref context => Ok(CallerCtx { pid: context.id.into(), uid: context.euid, gid: context.egid }),
-        }
-    }
-
     pub fn call(&self, a: usize, b: usize, c: usize, d: usize) -> Result<usize> {
-        match self.call_extended(Self::current_caller_ctx()?, [a, b, c, d])? {
+        match self.call_extended(current_caller_ctx()?, [a, b, c, d])? {
             Response::Regular(code) => Error::demux(code),
             Response::Fd(_) => {
                 if a & SYS_RET_FILE == SYS_RET_FILE {
@@ -427,7 +421,7 @@ impl Scheme for UserScheme {
     }
 
     fn dup(&self, old_id: usize, buf: &[u8]) -> Result<usize> {
-        self.kdup(old_id, buf, UserInner::current_caller_ctx()?).and_then(handle_open_res)
+        self.kdup(old_id, buf, current_caller_ctx()?).and_then(handle_open_res)
     }
 
     fn read(&self, file: usize, buf: &mut [u8]) -> Result<usize> {
diff --git a/src/syscall/fs.rs b/src/syscall/fs.rs
index 100214a6..792a4041 100644
--- a/src/syscall/fs.rs
+++ b/src/syscall/fs.rs
@@ -1,12 +1,13 @@
 //! Filesystem syscalls
 use alloc::sync::Arc;
+use syscall::CallerCtx;
 use core::str;
 use spin::RwLock;
 
 use crate::context::file::{FileDescriptor, FileDescription};
 use crate::context;
 use crate::memory::PAGE_SIZE;
-use crate::scheme::{self, FileHandle};
+use crate::scheme::{self, FileHandle, OpenResult, current_caller_ctx};
 use crate::syscall::data::{Packet, Stat};
 use crate::syscall::error::*;
 use crate::syscall::flag::*;
@@ -53,11 +54,8 @@ pub fn file_op_mut_slice(a: usize, fd: FileHandle, slice: &mut [u8]) -> Result<u
 
 /// Open syscall
 pub fn open(path: &str, flags: usize) -> Result<FileHandle> {
-    let (uid, gid, scheme_ns, umask) = {
-        let contexts = context::contexts();
-        let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
-        let context = context_lock.read();
-        (context.euid, context.egid, context.ens, context.umask)
+    let (pid, uid, gid, scheme_ns, umask) = match context::current()?.read() {
+        ref context => (context.id.into(), context.euid, context.egid, context.ens, context.umask),
     };
 
     let flags = (flags & (!0o777)) | ((flags & 0o777) & (!(umask & 0o777)));
@@ -67,23 +65,26 @@ pub fn open(path: &str, flags: usize) -> Result<FileHandle> {
     let scheme_name = parts.next().ok_or(Error::new(EINVAL))?;
     let reference = parts.next().unwrap_or("");
 
-    let (scheme_id, file_id) = {
+    let description = {
         let (scheme_id, scheme) = {
             let schemes = scheme::schemes();
             let (scheme_id, scheme) = schemes.get_name(scheme_ns, scheme_name).ok_or(Error::new(ENODEV))?;
             (scheme_id, Arc::clone(scheme))
         };
 
-        (scheme_id, scheme.open(reference, flags, uid, gid)?)
+        match scheme.kopen(reference, flags, CallerCtx { uid, gid, pid })? {
+            OpenResult::SchemeLocal(number) => Arc::new(RwLock::new(FileDescription {
+                namespace: scheme_ns,
+                scheme: scheme_id,
+                number,
+                flags: flags & !O_CLOEXEC,
+            })),
+            OpenResult::External(desc) => desc,
+        }
     };
 
     context::current()?.read().add_file(FileDescriptor {
-        description: Arc::new(RwLock::new(FileDescription {
-            namespace: scheme_ns,
-            scheme: scheme_id,
-            number: file_id,
-            flags: flags & !O_CLOEXEC,
-        })),
+        description,
         cloexec: flags & O_CLOEXEC == O_CLOEXEC,
     }).ok_or(Error::new(EMFILE))
 }
@@ -196,22 +197,25 @@ fn duplicate_file(fd: FileHandle, buf: &[u8]) -> Result<FileDescriptor> {
     } else {
         let description = file.description.read();
 
-        let new_id = {
+        let new_description = {
             let scheme = {
                 let schemes = scheme::schemes();
                 let scheme = schemes.get(description.scheme).ok_or(Error::new(EBADF))?;
                 Arc::clone(scheme)
             };
-            scheme.dup(description.number, buf)?
+            match scheme.kdup(description.number, buf, current_caller_ctx()?)? {
+                OpenResult::SchemeLocal(number) => Arc::new(RwLock::new(FileDescription {
+                    namespace: description.namespace,
+                    scheme: description.scheme,
+                    number,
+                    flags: description.flags,
+                })),
+                OpenResult::External(desc) => desc,
+            }
         };
 
         Ok(FileDescriptor {
-            description: Arc::new(RwLock::new(FileDescription {
-                namespace: description.namespace,
-                scheme: description.scheme,
-                number: new_id,
-                flags: description.flags,
-            })),
+            description: new_description,
             cloexec: false,
         })
     }
-- 
GitLab