1use crate::device::char::tty::tty_ctl::{
7 SCTL_TTY_GET_KBMODE, SCTL_TTY_GET_WINSIZE, SCTL_TTY_SET_KBMODE, SCTL_TTY_SET_WINSIZE,
8};
9use crate::{
10 device::{DeviceCapability, manager::DeviceManager},
11 fs::FileType,
12 object::KernelObject,
13 task::mytask,
14};
15pub const KDGKBMODE: u32 = 0x4B44; pub const KDGKBTYPE: u32 = 0x4B33; pub const KB_101: u32 = 0x02; pub const KDSKBMODE: u32 = 0x4B45; pub const VT_OPENQRY: u32 = 0x5600; pub const VT_GETMODE: u32 = 0x5601; pub const VT_SETMODE: u32 = 0x5602; pub const VT_GETSTATE: u32 = 0x5603; pub const VT_ACTIVATE: u32 = 0x5606; pub const VT_WAITACTIVE: u32 = 0x560C; pub const TIOCGWINSZ: u32 = 0x5413; pub const TIOCSWINSZ: u32 = 0x5414; pub const TCGETS: u32 = 0x5401; pub const TCSETS: u32 = 0x5402; pub const TCSETSW: u32 = 0x5403; pub const TCSETSF: u32 = 0x5404; pub const K_RAW: u32 = 0x00;
40pub const K_XLATE: u32 = 0x01;
41pub const K_MEDIUMRAW: u32 = 0x02;
45pub const K_UNICODE: u32 = 0x03;
46pub const K_OFF: u32 = 0x04;
47
48pub const KDSETMODE: u32 = 0x4B3A; pub const KDGETMODE: u32 = 0x4B3B; pub const KD_TEXT: u32 = 0x00;
52pub const KD_GRAPHICS: u32 = 0x01;
53
54#[repr(C)]
55struct Winsize {
56 ws_row: u16,
57 ws_col: u16,
58 ws_xpixel: u16,
59 ws_ypixel: u16,
60}
61
62#[repr(C)]
66struct LinuxTermios {
67 c_iflag: u32,
68 c_oflag: u32,
69 c_cflag: u32,
70 c_lflag: u32,
71 c_line: u8,
72 c_cc: [u8; 19],
73 c_ispeed: u32,
74 c_ospeed: u32,
75}
76
77const VEOF: usize = 4;
79const VTIME: usize = 5;
80const VMIN: usize = 6;
81
82pub fn handle_ioctl(
86 request: u32,
87 arg: usize,
88 kernel_object: &KernelObject,
89) -> Result<Option<usize>, ()> {
90 use crate::device::char::tty::tty_ctl::{
91 SCTL_TTY_GET_CANONICAL, SCTL_TTY_GET_ECHO, SCTL_TTY_GET_READ_POLICY,
92 SCTL_TTY_SET_CANONICAL, SCTL_TTY_SET_ECHO, SCTL_TTY_SET_READ_POLICY,
93 };
94
95 const LOG_TTY_IOCTL: bool = false;
96 match request {
97 KDGKBTYPE => {
98 let task = mytask().ok_or(())?;
100 let vaddr = arg as usize;
101 if let Some(paddr) = task.vm_manager.translate_vaddr(vaddr) {
102 unsafe { *(paddr as *mut u32) = KB_101; }
103 Ok(Some(0))
104 } else {
105 Ok(Some((-14_isize) as usize))
106 }
107 }
108 TCGETS | TCSETS | TCSETSW | TCSETSF => {
110 if LOG_TTY_IOCTL { crate::println!("[tty_ioctl] termios op {:#06x}", request); }
111 let is_tty = if let Some(file_obj) = kernel_object.as_file() {
113 if let Ok(metadata) = file_obj.metadata() {
114 if let FileType::CharDevice(info) = metadata.file_type {
115 if let Some(dev) = DeviceManager::get_manager().get_device(info.device_id) {
116 dev.capabilities().iter().any(|c| *c == DeviceCapability::Tty)
117 } else { false }
118 } else { false }
119 } else { false }
120 } else { false };
121 if !is_tty { return Err(()); }
122
123 match request {
124 TCGETS => {
125 let mut t = LinuxTermios {
126 c_iflag: 0,
127 c_oflag: 0,
128 c_cflag: 0,
129 c_lflag: 0,
130 c_line: 0,
131 c_cc: [0; 19],
132 c_ispeed: 0,
133 c_ospeed: 0,
134 };
135 let mut canonical = false;
136 let mut echo = true;
137 let mut min_ready: u16 = 1;
138 let mut timeout_ms: u16 = 0;
139 if let Some(control_ops) = kernel_object.as_control() {
140 if let Ok(val) = control_ops.control(SCTL_TTY_GET_CANONICAL, 0) { canonical = val != 0; }
141 if let Ok(val) = control_ops.control(SCTL_TTY_GET_ECHO, 0) { echo = val != 0; }
142 if let Ok(packed) = control_ops.control(SCTL_TTY_GET_READ_POLICY, 0) {
143 let packed_u = packed as u32;
144 min_ready = (packed_u & 0xFFFF) as u16;
145 timeout_ms = ((packed_u >> 16) & 0xFFFF) as u16;
146 }
147 }
148 if canonical { t.c_lflag |= 0x0000_0002; }
149 if echo { t.c_lflag |= 0x0000_0008; }
150 t.c_cc[VMIN] = core::cmp::min(min_ready as usize, 255) as u8;
151 let vtime_tenths = core::cmp::min(((timeout_ms as u32 + 99) / 100) as usize, 255) as u8;
152 t.c_cc[VTIME] = vtime_tenths;
153 t.c_cc[VEOF] = 0x04; let task = mytask().ok_or(())?;
155 let vaddr = arg as usize;
156 if let Some(paddr) = task.vm_manager.translate_vaddr(vaddr) {
157 unsafe { core::ptr::write(paddr as *mut LinuxTermios, t); }
158 Ok(Some(0))
159 } else { Err(()) }
160 }
161 _ => {
162 let task = mytask().ok_or(())?;
163 let vaddr = arg as usize;
164 if let Some(paddr) = task.vm_manager.translate_vaddr(vaddr) {
165 let t = unsafe { core::ptr::read(paddr as *const LinuxTermios) };
166 let canonical_new = (t.c_lflag & 0x0000_0002) != 0;
167 let echo_new = (t.c_lflag & 0x0000_0008) != 0;
168 let vmin = t.c_cc[VMIN] as u16;
169 let vtime_tenths = t.c_cc[VTIME] as u16;
170 let timeout_ms: u16 = vtime_tenths.saturating_mul(100);
171 if let Some(control_ops) = kernel_object.as_control() {
172 let prev_canonical = control_ops.control(SCTL_TTY_GET_CANONICAL, 0).unwrap_or(-1) != 0;
173 let prev_echo = control_ops.control(SCTL_TTY_GET_ECHO, 0).unwrap_or(-1) != 0;
174 let _ = control_ops.control(SCTL_TTY_SET_CANONICAL, if canonical_new { 1 } else { 0 });
175 let _ = control_ops.control(SCTL_TTY_SET_ECHO, if echo_new { 1 } else { 0 });
176 let packed = ((timeout_ms as u32) << 16) | (vmin as u32);
177 let _ = control_ops.control(SCTL_TTY_SET_READ_POLICY, packed as usize);
178 if LOG_TTY_IOCTL && (prev_canonical != canonical_new || prev_echo != echo_new) {
179 crate::println!("[linux TTY] termios change: canonical={} echo={} vmin={} timeout_ms={}",
180 canonical_new, echo_new, vmin, timeout_ms);
181 }
182 }
183 Ok(Some(0))
184 } else { Err(()) }
185 }
186 }
187 }
188 VT_GETSTATE => {
190 #[repr(C)]
192 struct VtStat { v_active: u16, v_signal: u16, v_state: u16 }
193 let task = mytask().ok_or(())?;
194 let vaddr = arg as usize;
195 if let Some(paddr) = task.vm_manager.translate_vaddr(vaddr) {
196 let state = VtStat { v_active: 1, v_signal: 0, v_state: 1 << 1 };
197 unsafe { core::ptr::write(paddr as *mut VtStat, state); }
198 Ok(Some(0))
199 } else {
200 Ok(Some((-14_isize) as usize))
201 }
202 }
203 VT_OPENQRY => {
205 let is_tty = if let Some(file_obj) = kernel_object.as_file() {
207 if let Ok(metadata) = file_obj.metadata() {
208 if let FileType::CharDevice(info) = metadata.file_type {
209 if let Some(dev) = DeviceManager::get_manager().get_device(info.device_id)
210 {
211 dev.capabilities()
212 .iter()
213 .any(|c| *c == DeviceCapability::Tty)
214 } else {
215 false
216 }
217 } else {
218 false
219 }
220 } else {
221 false
222 }
223 } else {
224 false
225 };
226 if !is_tty {
227 return Err(());
228 }
229
230 let task = mytask().ok_or(())?;
232 let vaddr = arg as usize;
233 if let Some(paddr) = task.vm_manager.translate_vaddr(vaddr) {
234 unsafe { *(paddr as *mut i32) = 1; }
235 Ok(Some(0))
236 } else {
237 Ok(Some((-14_isize) as usize))
238 }
239 }
240
241 VT_GETMODE => {
243 let is_tty = if let Some(file_obj) = kernel_object.as_file() {
245 if let Ok(metadata) = file_obj.metadata() {
246 if let FileType::CharDevice(info) = metadata.file_type {
247 if let Some(dev) = DeviceManager::get_manager().get_device(info.device_id) {
248 dev.capabilities().iter().any(|c| *c == DeviceCapability::Tty)
249 } else { false }
250 } else { false }
251 } else { false }
252 } else { false };
253 if !is_tty { return Err(()); }
254
255 let task = mytask().ok_or(())?;
257 let vaddr = arg as usize;
258 if let Some(paddr) = task.vm_manager.translate_vaddr(vaddr) {
259 unsafe { core::ptr::write_bytes(paddr as *mut u8, 0, 8); }
261 Ok(Some(0))
262 } else {
263 Ok(Some((-14_isize) as usize))
264 }
265 }
266
267 VT_SETMODE => {
269 let is_tty = if let Some(file_obj) = kernel_object.as_file() {
271 if let Ok(metadata) = file_obj.metadata() {
272 if let FileType::CharDevice(info) = metadata.file_type {
273 if let Some(dev) = DeviceManager::get_manager().get_device(info.device_id) {
274 dev.capabilities().iter().any(|c| *c == DeviceCapability::Tty)
275 } else { false }
276 } else { false }
277 } else { false }
278 } else { false };
279 if !is_tty { return Err(()); }
280 Ok(Some(0))
281 }
282
283 VT_ACTIVATE => {
285 let is_tty = if let Some(file_obj) = kernel_object.as_file() {
287 if let Ok(metadata) = file_obj.metadata() {
288 if let FileType::CharDevice(info) = metadata.file_type {
289 if let Some(dev) = DeviceManager::get_manager().get_device(info.device_id) {
290 dev.capabilities().iter().any(|c| *c == DeviceCapability::Tty)
291 } else { false }
292 } else { false }
293 } else { false }
294 } else { false };
295 if !is_tty { return Err(()); }
296
297 let vtno = arg as u32;
299 if vtno == 1 { Ok(Some(0)) } else { Ok(Some(0)) } }
301
302 0x5607 => { let is_tty = if let Some(file_obj) = kernel_object.as_file() {
306 if let Ok(metadata) = file_obj.metadata() {
307 if let FileType::CharDevice(info) = metadata.file_type {
308 if let Some(dev) = DeviceManager::get_manager().get_device(info.device_id) {
309 dev.capabilities().iter().any(|c| *c == DeviceCapability::Tty)
310 } else { false }
311 } else { false }
312 } else { false }
313 } else { false };
314 if !is_tty { return Err(()); }
315
316 Ok(Some(0))
317 }
318
319 0x560C => { let is_tty = if let Some(file_obj) = kernel_object.as_file() {
322 if let Ok(metadata) = file_obj.metadata() {
323 if let FileType::CharDevice(info) = metadata.file_type {
324 if let Some(dev) = DeviceManager::get_manager().get_device(info.device_id) {
325 dev.capabilities().iter().any(|c| *c == DeviceCapability::Tty)
326 } else { false }
327 } else { false }
328 } else { false }
329 } else { false };
330 if !is_tty { return Err(()); }
331 Ok(Some(0))
332 }
333
334 TIOCGWINSZ => {
336 if LOG_TTY_IOCTL { crate::println!("[tty_ioctl] TIOCGWINSZ"); }
337 if !is_tty_kernel_object(kernel_object) { return Err(()); }
338
339 let task = mytask().ok_or(())?;
340 let vaddr = arg as usize;
341 if let Some(paddr) = task.vm_manager.translate_vaddr(vaddr) {
342 let (cols, rows) = if let Some(control_ops) = kernel_object.as_control() {
343 match control_ops.control(SCTL_TTY_GET_WINSIZE, 0) {
344 Ok(packed) => {
345 let packed_u = packed as u32;
346 let cols = (packed_u >> 16) as u16;
347 let rows = (packed_u & 0xFFFF) as u16;
348 (cols, rows)
349 }
350 Err(_) => (80, 25),
351 }
352 } else {
353 (80, 25)
354 };
355
356 let ws = Winsize { ws_row: rows, ws_col: cols, ws_xpixel: 0, ws_ypixel: 0 };
357 unsafe { core::ptr::write(paddr as *mut Winsize, ws); }
358 Ok(Some(0))
359 } else {
360 Ok(Some((-14_isize) as usize))
361 }
362 }
363
364 TIOCSWINSZ => {
366 if LOG_TTY_IOCTL { crate::println!("[tty_ioctl] TIOCSWINSZ"); }
367 if !is_tty_kernel_object(kernel_object) { return Err(()); }
368
369 let task = mytask().ok_or(())?;
370 let vaddr = arg as usize;
371 if let Some(paddr) = task.vm_manager.translate_vaddr(vaddr) {
372 let ws = unsafe { core::ptr::read(paddr as *const Winsize) };
373 if let Some(control_ops) = kernel_object.as_control() {
374 let packed = ((ws.ws_col as usize) << 16) | (ws.ws_row as usize);
375 control_ops.control(SCTL_TTY_SET_WINSIZE, packed).map_err(|_| ())?;
376 } else {
377 return Err(());
378 }
379 Ok(Some(0))
380 } else {
381 Ok(Some((-14_isize) as usize))
382 }
383 }
384
385 KDGETMODE => {
387 if LOG_TTY_IOCTL { crate::println!("[tty_ioctl] KDGETMODE"); }
388 let task = mytask().ok_or(())?;
389 let vaddr = arg as usize;
390 if let Some(paddr) = task.vm_manager.translate_vaddr(vaddr) {
391 unsafe { *(paddr as *mut u32) = KD_TEXT; }
392 Ok(Some(0))
393 } else {
394 Ok(Some((-14_isize) as usize))
395 }
396 }
397 KDSETMODE => {
398 if LOG_TTY_IOCTL { crate::println!("[tty_ioctl] KDSETMODE mode={:#x}", arg as u32); }
399 let mode = arg as u32;
401 match mode {
402 KD_TEXT | KD_GRAPHICS => Ok(Some(0)),
403 _ => Err(()),
404 }
405 }
406
407 KDGKBMODE | KDSKBMODE => {
408 if LOG_TTY_IOCTL {
409 if request == KDGKBMODE { crate::println!("[tty_ioctl] KDGKBMODE"); } else { crate::println!("[tty_ioctl] KDSKBMODE -> {:#x}", arg as u32); }
410 }
411 let is_tty = if let Some(file_obj) = kernel_object.as_file() {
413 if let Ok(metadata) = file_obj.metadata() {
414 if let FileType::CharDevice(info) = metadata.file_type {
415 if let Some(dev) = DeviceManager::get_manager().get_device(info.device_id)
416 {
417 dev.capabilities()
418 .iter()
419 .any(|c| *c == DeviceCapability::Tty)
420 } else {
421 false
422 }
423 } else {
424 false
425 }
426 } else {
427 false
428 }
429 } else {
430 false
431 };
432 if !is_tty {
433 return Err(());
434 }
435
436 let control_ops = kernel_object.as_control().ok_or(())?;
438
439 if request == KDGKBMODE {
440 match control_ops.control(SCTL_TTY_GET_KBMODE, 0) {
442 Ok(v) => {
443 let task = mytask().ok_or(())?;
444 let mode: u32 = match v as u32 { 0 => K_XLATE, 1 => K_MEDIUMRAW, 2 => K_RAW, _ => K_RAW };
445 let vaddr = arg as usize;
446 if let Some(paddr) = task.vm_manager.translate_vaddr(vaddr) {
447 unsafe { *(paddr as *mut u32) = mode; }
448 Ok(Some(0))
449 } else { Ok(Some((-14_isize) as usize)) }
450 }
451 Err(_) => Err(()),
452 }
453 } else {
454 let mode = arg as u32;
456 let enable_canonical = match mode {
459 K_XLATE => true,
460 K_RAW | K_MEDIUMRAW | K_UNICODE | K_OFF => false,
461 _ => false, };
463 let arg_bool = if enable_canonical { 1usize } else { 0usize };
464 let prev_canonical = control_ops.control(SCTL_TTY_GET_CANONICAL, 0).unwrap_or(-1) != 0;
465 match control_ops.control(SCTL_TTY_SET_CANONICAL, arg_bool) {
466 Ok(_) => {
467 let new_canonical = enable_canonical;
468 if LOG_TTY_IOCTL && prev_canonical != new_canonical {
469 crate::println!("[linux TTY] keyboard mode -> canonical={}", new_canonical);
470 }
471 let kb = match mode { K_XLATE => 0usize, K_MEDIUMRAW => 1usize, K_RAW | K_UNICODE | K_OFF => 2usize, _ => 2usize };
473 let _ = control_ops.control(SCTL_TTY_SET_KBMODE, kb);
474 Ok(Some(0))
475 },
476 Err(_) => Err(()),
477 }
478 }
479 }
480 0x4B46 => {
482 #[repr(C)]
483 struct KbEntry { kb_table: u8, kb_index: u8, kb_value: u16 }
484
485 if !is_tty_kernel_object(kernel_object) { return Err(()); }
486
487 fn us_kmap(norm: bool, idx: usize) -> u16 {
488 const KT_FN: u16 = 1;
490 const KT_CUR: u16 = 6;
491 const K_DOWN: u16 = (KT_CUR << 8) | 0; const K_LEFT: u16 = (KT_CUR << 8) | 1; const K_RIGHT: u16 = (KT_CUR << 8) | 2; const K_UP: u16 = (KT_CUR << 8) | 3; const K_FIND: u16 = (KT_FN << 8) | 20; const K_INSERT: u16 = (KT_FN << 8) | 21; const K_REMOVE: u16 = (KT_FN << 8) | 22; const K_SELECT: u16 = (KT_FN << 8) | 23; const K_PGUP: u16 = (KT_FN << 8) | 24; const K_PGDN: u16 = (KT_FN << 8) | 25; let ascii_passthrough = |i: usize| -> u16 {
504 if (b'a' as usize..=b'z' as usize).contains(&i)
505 || (b'0' as usize..=b'9' as usize).contains(&i)
506 || i == b' ' as usize || i == b'\t' as usize || i == b'\n' as usize
507 || [b'-', b'=', b'[', b']', b'\\', b';', b'\'', b'`', b',', b'.', b'/'].iter().any(|c| *c as usize == i)
508 { i as u16 } else { 0 }
509 };
510 let ascii_shift = |i: usize| -> u16 {
511 match i as u8 {
512 b'a'..=b'z' => (i as u8).to_ascii_uppercase() as u16,
513 b'1' => b'!' as u16, b'2' => b'@' as u16, b'3' => b'#' as u16,
514 b'4' => b'$' as u16, b'5' => b'%' as u16, b'6' => b'^' as u16,
515 b'7' => b'&' as u16, b'8' => b'*' as u16, b'9' => b'(' as u16,
516 b'0' => b')' as u16,
517 b'-' => b'_' as u16, b'=' => b'+' as u16,
518 b'[' => b'{' as u16, b']' => b'}' as u16, b'\\' => b'|' as u16,
519 b';' => b':' as u16, b'\'' => b'"' as u16, b'`' => b'~' as u16,
520 b',' => b'<' as u16, b'.' => b'>' as u16, b'/' => b'?' as u16,
521 other => other as u16,
522 }
523 };
524 match (norm, idx) {
525 (_, 103) => K_UP,
529 (_, 108) => K_DOWN,
530 (_, 105) => K_LEFT,
531 (_, 106) => K_RIGHT,
532 (_, 102) => K_FIND, (_, 107) => K_SELECT, (_, 104) => K_PGUP,
535 (_, 109) => K_PGDN,
536 (_, 110) => K_INSERT,
537 (_, 111) => K_REMOVE,
538 (true, 2) => b'1' as u16, (true, 3) => b'2' as u16, (true, 4) => b'3' as u16,
539 (true, 5) => b'4' as u16, (true, 6) => b'5' as u16, (true, 7) => b'6' as u16,
540 (true, 8) => b'7' as u16, (true, 9) => b'8' as u16, (true, 10) => b'9' as u16,
541 (true, 11) => b'0' as u16, (true, 12) => b'-' as u16, (true, 13) => b'=' as u16,
542 (true, 15) => b'\t' as u16, (true, 28) => b'\n' as u16, (true, 57) => b' ' as u16,
543 (true, 16) => b'q' as u16, (true, 17) => b'w' as u16, (true, 18) => b'e' as u16,
544 (true, 19) => b'r' as u16, (true, 20) => b't' as u16, (true, 21) => b'y' as u16,
545 (true, 22) => b'u' as u16, (true, 23) => b'i' as u16, (true, 24) => b'o' as u16,
546 (true, 25) => b'p' as u16, (true, 26) => b'[' as u16, (true, 27) => b']' as u16,
547 (true, 30) => b'a' as u16, (true, 31) => b's' as u16, (true, 32) => b'd' as u16,
548 (true, 33) => b'f' as u16, (true, 34) => b'g' as u16, (true, 35) => b'h' as u16,
549 (true, 36) => b'j' as u16, (true, 37) => b'k' as u16, (true, 38) => b'l' as u16,
550 (true, 39) => b';' as u16, (true, 40) => b'\'' as u16, (true, 41) => b'`' as u16,
551 (true, 44) => b'z' as u16, (true, 45) => b'x' as u16, (true, 46) => b'c' as u16,
552 (true, 47) => b'v' as u16, (true, 48) => b'b' as u16, (true, 49) => b'n' as u16,
553 (true, 50) => b'm' as u16, (true, 51) => b',' as u16, (true, 52) => b'.' as u16,
554 (true, 53) => b'/' as u16,
555 (false, 2) => b'!' as u16, (false, 3) => b'@' as u16, (false, 4) => b'#' as u16,
556 (false, 5) => b'$' as u16, (false, 6) => b'%' as u16, (false, 7) => b'^' as u16,
557 (false, 8) => b'&' as u16, (false, 9) => b'*' as u16, (false, 10) => b'(' as u16,
558 (false, 11) => b')' as u16, (false, 12) => b'_' as u16, (false, 13) => b'+' as u16,
559 (false, 15) => b'\t' as u16, (false, 28) => b'\n' as u16, (false, 57) => b' ' as u16,
560 (false, 16) => b'Q' as u16, (false, 17) => b'W' as u16, (false, 18) => b'E' as u16,
561 (false, 19) => b'R' as u16, (false, 20) => b'T' as u16, (false, 21) => b'Y' as u16,
562 (false, 22) => b'U' as u16, (false, 23) => b'I' as u16, (false, 24) => b'O' as u16,
563 (false, 25) => b'P' as u16, (false, 26) => b'{' as u16, (false, 27) => b'}' as u16,
564 (false, 30) => b'A' as u16, (false, 31) => b'S' as u16, (false, 32) => b'D' as u16,
565 (false, 33) => b'F' as u16, (false, 34) => b'G' as u16, (false, 35) => b'H' as u16,
566 (false, 36) => b'J' as u16, (false, 37) => b'K' as u16, (false, 38) => b'L' as u16,
567 (false, 39) => b':' as u16, (false, 40) => b'"' as u16, (false, 41) => b'~' as u16,
568 (false, 44) => b'Z' as u16, (false, 45) => b'X' as u16, (false, 46) => b'C' as u16,
569 (false, 47) => b'V' as u16, (false, 48) => b'B' as u16, (false, 49) => b'N' as u16,
570 (false, 50) => b'M' as u16, (false, 51) => b'<' as u16, (false, 52) => b'>' as u16,
571 (false, 53) => b'?' as u16,
572 _ => {
573 if norm { ascii_passthrough(idx) } else { ascii_shift(idx) }
575 },
576 }
577 }
578
579 let task = mytask().ok_or(())?;
580 let vaddr = arg as usize;
581 if let Some(paddr) = task.vm_manager.translate_vaddr(vaddr) {
582 unsafe {
583 let mut e = core::ptr::read(paddr as *const KbEntry);
584 let idx = e.kb_index as usize;
585 let val = match e.kb_table { 0 => us_kmap(true, idx), 1 => us_kmap(false, idx), _ => 0 };
586 e.kb_value = val;
587 core::ptr::write(paddr as *mut KbEntry, e);
588 }
589 Ok(Some(0))
590 } else {
591 Ok(Some((-14_isize) as usize))
592 }
593 }
594 0x4B47 => {
595 crate::println!("[tty_ioctl] KDSKBENT");
596 let is_tty = if let Some(file_obj) = kernel_object.as_file() {
598 if let Ok(metadata) = file_obj.metadata() {
599 if let FileType::CharDevice(info) = metadata.file_type {
600 if let Some(dev) = DeviceManager::get_manager().get_device(info.device_id) {
601 dev.capabilities().iter().any(|c| *c == DeviceCapability::Tty)
602 } else { false }
603 } else { false }
604 } else { false }
605 } else { false };
606 if !is_tty { return Err(()); }
607 Ok(Some(0))
608 }
609 _ => Ok(None),
610 }
611}
612
613fn is_tty_kernel_object(kernel_object: &KernelObject) -> bool {
614 if let Some(file_obj) = kernel_object.as_file() {
615 if let Ok(metadata) = file_obj.metadata() {
616 if let FileType::CharDevice(info) = metadata.file_type {
617 if let Some(dev) = DeviceManager::get_manager().get_device(info.device_id) {
618 return dev
619 .capabilities()
620 .iter()
621 .any(|c| *c == DeviceCapability::Tty);
622 }
623 }
624 }
625 }
626 false
627}