shadow_rs/host/syscall/handler/
ioctl.rs
1use linux_api::errno::Errno;
2use linux_api::fcntl::DescriptorFlags;
3use linux_api::ioctls::IoctlRequest;
4use log::debug;
5use shadow_shim_helper_rs::syscall_types::ForeignPtr;
6
7use crate::cshadow as c;
8use crate::host::descriptor::{CompatFile, FileStatus};
9use crate::host::syscall::handler::{SyscallContext, SyscallHandler};
10use crate::host::syscall::type_formatting::SyscallNonDeterministicArg;
11use crate::host::syscall::types::SyscallResult;
12
13impl SyscallHandler {
14 log_syscall!(
15 ioctl,
16 std::ffi::c_int,
17 std::ffi::c_uint,
18 std::ffi::c_uint,
19 SyscallNonDeterministicArg<std::ffi::c_ulong>,
20 );
21 pub fn ioctl(
22 ctx: &mut SyscallContext,
23 fd: std::ffi::c_uint,
24 cmd: std::ffi::c_uint,
25 arg_ptr: ForeignPtr<()>,
26 ) -> SyscallResult {
27 log::trace!("Called ioctl() on fd {fd} with cmd {cmd}");
28
29 let Ok(cmd) = IoctlRequest::try_from(cmd) else {
30 debug!("Unrecognized ioctl cmd {cmd}");
31 return Err(Errno::EINVAL.into());
32 };
33
34 let file = {
36 let mut desc_table = ctx.objs.thread.descriptor_table_borrow_mut(ctx.objs.host);
37 let desc = Self::get_descriptor_mut(&mut desc_table, fd)?;
38
39 if cmd == IoctlRequest::FIOCLEX {
41 let mut flags = desc.flags();
42 flags.insert(DescriptorFlags::FD_CLOEXEC);
43 desc.set_flags(flags);
44
45 return Ok(0.into());
46 }
47
48 if cmd == IoctlRequest::FIONCLEX {
50 let mut flags = desc.flags();
51 flags.remove(DescriptorFlags::FD_CLOEXEC);
52 desc.set_flags(flags);
53
54 return Ok(0.into());
55 }
56
57 let file = match desc.file() {
60 CompatFile::New(file) => file,
61 CompatFile::Legacy(_) => {
63 drop(desc_table);
64 return Self::legacy_syscall(c::syscallhandler_ioctl, ctx);
65 }
66 };
67
68 file.inner_file().clone()
69 };
70
71 let mut file = file.borrow_mut();
72
73 if cmd == IoctlRequest::FIONBIO {
75 let arg_ptr = arg_ptr.cast::<std::ffi::c_int>();
76 let arg = ctx.objs.process.memory_borrow_mut().read(arg_ptr)?;
77
78 let mut status = file.status();
79 status.set(FileStatus::NONBLOCK, arg != 0);
80 file.set_status(status);
81
82 return Ok(0.into());
83 }
84
85 file.ioctl(cmd, arg_ptr, &mut ctx.objs.process.memory_borrow_mut())
87 }
88}