Resolve `semget01` failure by fixing key limit and adding `IPC_STAT`
This commit is contained in:
parent
85f17ff159
commit
226ea2865c
|
|
@ -7,7 +7,7 @@ futex, set_robust_list, and get_robust_list
|
|||
under this category.
|
||||
-->
|
||||
|
||||
## `System V semaphore`
|
||||
## System V semaphore
|
||||
|
||||
### `semget`
|
||||
|
||||
|
|
@ -80,10 +80,17 @@ semctl(
|
|||
semnum,
|
||||
cmd = GETVAL | GETPID | GETNCNT | GETZCNT
|
||||
);
|
||||
|
||||
// Retrieve a copy of the `semid_ds` kernel structure for the specified semaphore set
|
||||
semctl(
|
||||
semid,
|
||||
semnum,
|
||||
cmd = IPC_STAT,
|
||||
arg
|
||||
);
|
||||
```
|
||||
|
||||
Unsupported commands:
|
||||
* `IPC_STAT`
|
||||
* `IPC_INFO`
|
||||
* `SEM_INFO`
|
||||
* `SEM_STAT`
|
||||
|
|
|
|||
|
|
@ -51,6 +51,37 @@ pub struct SemaphoreSet {
|
|||
sem_otime: AtomicU64,
|
||||
}
|
||||
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/ipcbuf.h
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone, Default, Pod)]
|
||||
pub struct IpcPerm {
|
||||
key: u32,
|
||||
uid: u32,
|
||||
gid: u32,
|
||||
cuid: u32,
|
||||
cgid: u32,
|
||||
mode: u16,
|
||||
_pad1: u16,
|
||||
seq: u16,
|
||||
_pad2: u16,
|
||||
_unused1: u64,
|
||||
_unused2: u64,
|
||||
}
|
||||
|
||||
// https://github.com/torvalds/linux/blob/master/arch/x86/include/uapi/asm/sembuf.h
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone, Default, Pod)]
|
||||
pub struct SemidDs {
|
||||
sem_perm: IpcPerm,
|
||||
sem_otime: u64,
|
||||
_unused1: u64,
|
||||
sem_ctime: u64,
|
||||
_unused2: u64,
|
||||
sem_nsems: u64,
|
||||
_unused3: u64,
|
||||
_unused4: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct SemSetInner {
|
||||
/// Semaphores
|
||||
|
|
@ -196,6 +227,26 @@ impl SemaphoreSet {
|
|||
}),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn semid_ds(&self) -> SemidDs {
|
||||
let ipc_perm = IpcPerm {
|
||||
key: self.permission.key() as u32,
|
||||
uid: self.permission.uid().into(),
|
||||
gid: self.permission.gid().into(),
|
||||
cuid: self.permission.cuid().into(),
|
||||
cgid: self.permission.cguid().into(),
|
||||
mode: self.permission.mode(),
|
||||
..IpcPerm::default()
|
||||
};
|
||||
|
||||
SemidDs {
|
||||
sem_perm: ipc_perm,
|
||||
sem_otime: self.sem_otime.load(Ordering::Relaxed),
|
||||
sem_ctime: self.sem_ctime.load(Ordering::Relaxed),
|
||||
sem_nsems: self.nsems as u64,
|
||||
..SemidDs::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for SemaphoreSet {
|
||||
|
|
|
|||
|
|
@ -92,6 +92,12 @@ pub fn sys_semctl(
|
|||
|
||||
return Ok(SyscallReturn::Return(cnt as isize));
|
||||
}
|
||||
IpcControlCmd::IPC_STAT => {
|
||||
check_and_ctl(semid, PermissionMode::READ, |sem_set| {
|
||||
let semid_ds = sem_set.semid_ds();
|
||||
ctx.user_space().write_val(arg as Vaddr, &semid_ds)
|
||||
})?;
|
||||
}
|
||||
_ => todo!("Need to support {:?} in SYS_SEMCTL", cmd),
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use super::SyscallReturn;
|
|||
use crate::{
|
||||
ipc::{
|
||||
semaphore::system_v::{
|
||||
sem_set::{check_sem, create_sem_set, create_sem_set_with_id, SEMMSL},
|
||||
sem_set::{check_sem, create_sem_set, create_sem_set_with_id, SEMMNI, SEMMSL},
|
||||
PermissionMode,
|
||||
},
|
||||
IpcFlags,
|
||||
|
|
@ -32,7 +32,7 @@ pub fn sys_semget(key: i32, nsems: i32, semflags: i32, ctx: &Context) -> Result<
|
|||
|
||||
// Create a new semaphore set directly
|
||||
const IPC_NEW: i32 = 0;
|
||||
if key == IPC_NEW {
|
||||
if key == IPC_NEW || (key as usize > SEMMNI && flags.contains(IpcFlags::IPC_CREAT)) {
|
||||
if nsems == 0 {
|
||||
return_errno!(Errno::EINVAL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1290,7 +1290,7 @@ select03
|
|||
# semctl08
|
||||
# semctl09
|
||||
|
||||
# semget01
|
||||
semget01
|
||||
# semget02
|
||||
# semget05
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue