MCPcopy Index your code
hub / github.com/RustPython/RustPython / ioctl

Function ioctl

crates/stdlib/src/fcntl.rs:93–147  ·  view source on GitHub ↗
(
        _io::Fildes(fd): _io::Fildes,
        request: i64,
        arg: OptionalArg<Either<Either<ArgMemoryBuffer, ArgStrOrBytesLike>, i32>>,
        mutate_flag: OptionalArg<bool>,
        vm: &Vi

Source from the content-addressed store, hash-verified

91
92 #[pyfunction]
93 fn ioctl(
94 _io::Fildes(fd): _io::Fildes,
95 request: i64,
96 arg: OptionalArg<Either<Either<ArgMemoryBuffer, ArgStrOrBytesLike>, i32>>,
97 mutate_flag: OptionalArg<bool>,
98 vm: &VirtualMachine,
99 ) -> PyResult {
100 // Convert to unsigned - handles both positive u32 values and negative i32 values
101 // that represent the same bit pattern (e.g., TIOCSWINSZ on some platforms).
102 // First truncate to u32 (takes lower 32 bits), then zero-extend to c_ulong.
103 let request = (request as u32) as libc::c_ulong;
104 let arg = arg.unwrap_or_else(|| Either::B(0));
105 match arg {
106 Either::A(buf_kind) => {
107 const BUF_SIZE: usize = 1024;
108 let mut buf = [0u8; BUF_SIZE + 1]; // nul byte
109 let mut fill_buf = |b: &[u8]| {
110 if b.len() > BUF_SIZE {
111 return Err(vm.new_value_error("fcntl string arg too long"));
112 }
113 buf[..b.len()].copy_from_slice(b);
114 Ok(b.len())
115 };
116 let buf_len = match buf_kind {
117 Either::A(rw_arg) => {
118 let mutate_flag = mutate_flag.unwrap_or(true);
119 let mut arg_buf = rw_arg.borrow_buf_mut();
120 if mutate_flag {
121 let ret =
122 unsafe { libc::ioctl(fd, request as _, arg_buf.as_mut_ptr()) };
123 if ret < 0 {
124 return Err(vm.new_last_errno_error());
125 }
126 return Ok(vm.ctx.new_int(ret).into());
127 }
128 // treat like an immutable buffer
129 fill_buf(&arg_buf)?
130 }
131 Either::B(ro_buf) => fill_buf(&ro_buf.borrow_bytes())?,
132 };
133 let ret = unsafe { libc::ioctl(fd, request as _, buf.as_mut_ptr()) };
134 if ret < 0 {
135 return Err(vm.new_last_errno_error());
136 }
137 Ok(vm.ctx.new_bytes(buf[..buf_len].to_vec()).into())
138 }
139 Either::B(i) => {
140 let ret = unsafe { libc::ioctl(fd, request as _, i) };
141 if ret < 0 {
142 return Err(vm.new_last_errno_error());
143 }
144 Ok(vm.ctx.new_int(ret).into())
145 }
146 }
147 }
148
149 // XXX: at the time of writing, wasi and redox don't have the necessary constants/function
150 #[cfg(not(any(target_os = "wasi", target_os = "redox")))]

Callers 3

slave_openFunction · 0.90
getheightwidthMethod · 0.90
getpendingMethod · 0.90

Calls 10

as_mut_ptrMethod · 0.80
new_last_errno_errorMethod · 0.80
borrow_bytesMethod · 0.80
to_vecMethod · 0.80
BClass · 0.50
ErrClass · 0.50
lenMethod · 0.45
borrow_buf_mutMethod · 0.45
new_intMethod · 0.45
new_bytesMethod · 0.45

Tested by

no test coverage detected