From 4530253a99160cd5280a0348778b0ca0b330d572 Mon Sep 17 00:00:00 2001 From: Yuke Peng Date: Sat, 10 Aug 2024 18:50:59 +0800 Subject: [PATCH] Implement semget syscall --- docs/src/kernel/linux-compatibility.md | 2 +- kernel/aster-nix/src/syscall/arch/x86.rs | 2 + kernel/aster-nix/src/syscall/mod.rs | 1 + kernel/aster-nix/src/syscall/semget.rs | 66 ++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 kernel/aster-nix/src/syscall/semget.rs diff --git a/docs/src/kernel/linux-compatibility.md b/docs/src/kernel/linux-compatibility.md index 72a565eb0..250384c6b 100644 --- a/docs/src/kernel/linux-compatibility.md +++ b/docs/src/kernel/linux-compatibility.md @@ -84,7 +84,7 @@ provided by Linux on x86-64 architecture. | 61 | wait4 | ✅ | | 62 | kill | ✅ | | 63 | uname | ✅ | -| 64 | semget | ❌ | +| 64 | semget | ✅ | | 65 | semop | ❌ | | 66 | semctl | ❌ | | 67 | shmdt | ❌ | diff --git a/kernel/aster-nix/src/syscall/arch/x86.rs b/kernel/aster-nix/src/syscall/arch/x86.rs index b28877d4e..d8eeaed0c 100644 --- a/kernel/aster-nix/src/syscall/arch/x86.rs +++ b/kernel/aster-nix/src/syscall/arch/x86.rs @@ -89,6 +89,7 @@ use crate::syscall::{ sched_getaffinity::sys_sched_getaffinity, sched_yield::sys_sched_yield, select::sys_select, + semget::sys_semget, sendfile::sys_sendfile, sendmsg::sys_sendmsg, sendto::sys_sendto, @@ -190,6 +191,7 @@ impl_syscall_nums_and_dispatch_fn! { SYS_WAIT4 = 61 => sys_wait4(args[..4]); SYS_KILL = 62 => sys_kill(args[..2]); SYS_UNAME = 63 => sys_uname(args[..1]); + SYS_SEMGET = 64 => sys_semget(args[..3]); SYS_FCNTL = 72 => sys_fcntl(args[..3]); SYS_FLOCK = 73 => sys_flock(args[..2]); SYS_FSYNC = 74 => sys_fsync(args[..1]); diff --git a/kernel/aster-nix/src/syscall/mod.rs b/kernel/aster-nix/src/syscall/mod.rs index cd0b40e4f..876e0f70b 100644 --- a/kernel/aster-nix/src/syscall/mod.rs +++ b/kernel/aster-nix/src/syscall/mod.rs @@ -96,6 +96,7 @@ mod rt_sigsuspend; mod sched_getaffinity; mod sched_yield; mod select; +mod semget; mod sendfile; mod sendmsg; mod sendto; diff --git a/kernel/aster-nix/src/syscall/semget.rs b/kernel/aster-nix/src/syscall/semget.rs new file mode 100644 index 000000000..515a20262 --- /dev/null +++ b/kernel/aster-nix/src/syscall/semget.rs @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MPL-2.0 + +use super::SyscallReturn; +use crate::{ + ipc::{ + semaphore::system_v::{ + sem_set::{check_sem, create_sem_set, create_sem_set_with_id, SEMMSL}, + PermissionMode, + }, + IpcFlags, + }, + prelude::*, +}; + +pub fn sys_semget(key: i32, nsems: i32, semflags: i32, ctx: &Context) -> Result { + if nsems < 0 || nsems as usize > SEMMSL { + return_errno!(Errno::EINVAL); + } + + let flags = IpcFlags::from_bits_truncate(semflags as u32); + let mode: u16 = (semflags as u32 & 0x1FF) as u16; + let nsems = nsems as usize; + let credentials = ctx.posix_thread.credentials(); + + debug!( + "[sys_semget] key = {}, nsems = {}, flags = {:?}", + key, nsems, semflags + ); + + // Create a new semaphore set directly + const IPC_NEW: i32 = 0; + if key == IPC_NEW { + if nsems == 0 { + return_errno!(Errno::EINVAL); + } + return Ok(SyscallReturn::Return( + create_sem_set(nsems, mode, credentials)? as isize, + )); + } + + // Get a semaphore set, and create if necessary + match check_sem( + key, + Some(nsems), + PermissionMode::ALTER | PermissionMode::READ, + ) { + Ok(_) => { + if flags.contains(IpcFlags::IPC_CREAT | IpcFlags::IPC_EXCL) { + return_errno!(Errno::EEXIST); + } + } + Err(err) => { + let need_create = err.error() == Errno::ENOENT && flags.contains(IpcFlags::IPC_CREAT); + if !need_create { + return Err(err); + } + if nsems == 0 { + return_errno!(Errno::EINVAL); + } + + create_sem_set_with_id(key, nsems, mode, credentials)? + } + }; + + Ok(SyscallReturn::Return(key as isize)) +}