mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-15 16:26:48 +00:00
Implement semget syscall
This commit is contained in:
parent
b7a5f797de
commit
4530253a99
@ -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 | ❌ |
|
||||
|
@ -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]);
|
||||
|
@ -96,6 +96,7 @@ mod rt_sigsuspend;
|
||||
mod sched_getaffinity;
|
||||
mod sched_yield;
|
||||
mod select;
|
||||
mod semget;
|
||||
mod sendfile;
|
||||
mod sendmsg;
|
||||
mod sendto;
|
||||
|
66
kernel/aster-nix/src/syscall/semget.rs
Normal file
66
kernel/aster-nix/src/syscall/semget.rs
Normal file
@ -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<SyscallReturn> {
|
||||
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))
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user