Implement the syscall `shmctl`

This commit is contained in:
Zhe Tang 2025-12-30 03:25:37 +00:00
parent 85536a548f
commit 5348f4fc26
1 changed files with 63 additions and 0 deletions

View File

@ -35,4 +35,67 @@ bitflags! {
}
pub fn sys_shmctl(id: i32, cmd: i32, buf: u64, _ctx: &Context) -> Result<SyscallReturn> {
debug!("[sys_shmctl] id = {}, cmd = {}, buf = {:#x}", id, cmd, buf);
if id < 0 {
return_errno!(Errno::EINVAL);
}
let manager = SHM_OBJ_MANAGER.get().ok_or(Errno::EINVAL)?;
let shm_obj = {
let guard = manager.read();
match guard.get_shm_obj(id as u64) {
Some(shm_obj) => shm_obj,
None => return_errno!(Errno::EINVAL),
}
};
let cmd = ShmCtlCmd::from_bits(cmd).ok_or(Errno::EINVAL)?;
match cmd {
ShmCtlCmd::IPC_RMID => {
let mut guard = manager.write();
// Remove key mapping immediately to block further lookups by key
if let Some(key) = shm_obj.key() {
guard.remove_key_mapping(key);
}
// Mark the segment to be destroyed
shm_obj.set_deleted();
// Try to delete the shared memory object when no process is attached
guard.try_delete_shm_obj(id as u64)?;
Ok(SyscallReturn::Return(0))
}
ShmCtlCmd::IPC_SET => {
let shm_ds: ShmidDs = current_userspace!().read_val(buf as usize)?;
// FIXME: Check if the current process has the permission to set
// the attributes
// Update the attributes of the shared memory object
shm_obj.set_attributes(
InodeMode::from_bits_truncate(shm_ds.shm_perm.mode),
shm_ds.shm_perm.uid,
shm_ds.shm_perm.gid,
)?;
Ok(SyscallReturn::Return(0))
}
ShmCtlCmd::IPC_STAT => {
// Get the attributes of the shared memory object
let shm_ds = shm_obj.get_attributes()?;
// Write the attributes to the user space
current_userspace!().write_val(buf as usize, &shm_ds)?;
Ok(SyscallReturn::Return(0))
}
_ => {
warn!("Unsupported shmctl command: {:?}", cmd);
return_errno!(Errno::EINVAL);
}
}
}