diff --git a/src/header/stdlib/mod.rs b/src/header/stdlib/mod.rs index 6b7af6994c6686435cce0fa81b90b2ed230e0225..d36e13a0c92bc6f5238a591e99c600ed648bffdf 100644 --- a/src/header/stdlib/mod.rs +++ b/src/header/stdlib/mod.rs @@ -618,7 +618,7 @@ pub unsafe extern "C" fn realpath(pathname: *const c_char, resolved: *mut c_char resolved }; - let mut out = slice::from_raw_parts_mut(ptr as *mut u8, limits::PATH_MAX); + let out = slice::from_raw_parts_mut(ptr as *mut u8, limits::PATH_MAX); { let file = match File::open(&CStr::from_ptr(pathname), O_PATH | O_CLOEXEC) { Ok(file) => file, diff --git a/src/header/sys_ioctl/redox.rs b/src/header/sys_ioctl/redox.rs index 0b389bb7c603787c8201c44590421258393fcb5f..b0f0d1dd8e76242b5647e321cd522a6ca8748882 100644 --- a/src/header/sys_ioctl/redox.rs +++ b/src/header/sys_ioctl/redox.rs @@ -9,109 +9,104 @@ use platform::types::*; use super::winsize; +pub const TCGETS: c_ulong = 0x5401; +pub const TCSETS: c_ulong = 0x5402; + +pub const TCFLSH: c_ulong = 0x540B; + +pub const TIOCGPGRP: c_ulong = 0x540F; +pub const TIOCSPGRP: c_ulong = 0x5410; + +pub const TIOCGWINSZ: c_ulong = 0x5413; +pub const TIOCSWINSZ: c_ulong = 0x5414; + +fn dup_read<T>(fd: c_int, name: &str, t: &mut T) -> syscall::Result<usize> { + let dup = syscall::dup(fd as usize, name.as_bytes())?; + + let size = mem::size_of::<T>(); + + let res = syscall::read(dup, unsafe { + slice::from_raw_parts_mut(t as *mut T as *mut u8, size) + }); + + let _ = syscall::close(dup); + + res.map(|bytes| bytes/size) +} + +fn dup_write<T>(fd: c_int, name: &str, t: &T) -> syscall::Result<usize> { + let dup = syscall::dup(fd as usize, name.as_bytes())?; + + let size = mem::size_of::<T>(); + + let res = syscall::write(dup, unsafe { + slice::from_raw_parts(t as *const T as *const u8, size) + }); + + let _ = syscall::close(dup); + + res.map(|bytes| bytes/size) +} + #[no_mangle] pub unsafe extern "C" fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> c_int { match request { TCGETS => { - let dup = e(syscall::dup(fd as usize, b"termios")); - if dup == !0 { - return -1; - } - - let count = e(syscall::read(dup, unsafe { - slice::from_raw_parts_mut(out as *mut u8, mem::size_of::<termios::termios>()) - })); - let _ = syscall::close(dup); - - if count == !0 { - return -1; + let termios = &mut *(out as *mut termios::termios); + if e(dup_read(fd, "termios", termios)) == !0 { + -1 + } else { + 0 } - 0 } TCSETS => { - let dup = e(syscall::dup(fd as usize, b"termios")); - if dup == !0 { - return -1; + let termios = &*(out as *const termios::termios); + if e(dup_write(fd, "termios", termios)) == !0 { + -1 + } else { + 0 } - - let count = e(syscall::write(dup, unsafe { - slice::from_raw_parts(out as *const u8, mem::size_of::<termios::termios>()) - })); - let _ = syscall::close(dup); - - if count == !0 { - return -1; + }, + TCFLSH => { + let queue = out as c_int; + if e(dup_write(fd, "flush", &queue)) == !0 { + -1 + } else { + 0 } - 0 }, TIOCGPGRP => { - let dup = e(syscall::dup(fd as usize, b"pgrp")); - if dup == !0 { - return -1; - } - - let count = e(syscall::read( - dup, - slice::from_raw_parts_mut(out as *mut u8, mem::size_of::<pid_t>()) - )); - let _ = syscall::close(dup); - - if count == !0 { - return -1; + let pgrp = &mut *(out as *mut pid_t); + if e(dup_read(fd, "pgrp", pgrp)) == !0 { + -1 + } else { + 0 } - 0 }, TIOCSPGRP => { - let dup = e(syscall::dup(fd as usize, b"pgrp")); - if dup == !0 { - return -1; + let pgrp = &*(out as *const pid_t); + if e(dup_write(fd, "pgrp", pgrp)) == !0 { + -1 + } else { + 0 } - - let count = e(syscall::write( - dup, - slice::from_raw_parts(out as *const u8, mem::size_of::<pid_t>()) - )); - let _ = syscall::close(dup); - - if count == !0 { - return -1; - } - 0 }, TIOCGWINSZ => { - let dup = e(syscall::dup(fd as usize, b"winsize")); - if dup == !0 { - return -1; - } - - let count = e(syscall::read( - dup, - slice::from_raw_parts_mut(out as *mut u8, mem::size_of::<winsize>()) - )); - let _ = syscall::close(dup); - - if count == !0 { - return -1; + let winsize = &mut *(out as *mut winsize); + if e(dup_read(fd, "winsize", winsize)) == !0 { + -1 + } else { + 0 } - 0 }, TIOCSWINSZ => { - let dup = e(syscall::dup(fd as usize, b"winsize")); - if dup == !0 { - return -1; + let winsize = &*(out as *const winsize); + if e(dup_write(fd, "winsize", winsize)) == !0 { + -1 + } else { + 0 } - - let count = e(syscall::write( - dup, - slice::from_raw_parts(out as *const u8, mem::size_of::<winsize>()) - )); - let _ = syscall::close(dup); - - if count == !0 { - return -1; - } - 0 }, _ => { platform::errno = errno::EINVAL; @@ -119,12 +114,3 @@ pub unsafe extern "C" fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> } } } - -pub const TCGETS: c_ulong = 0x5401; -pub const TCSETS: c_ulong = 0x5402; - -pub const TIOCGPGRP: c_ulong = 0x540F; -pub const TIOCSPGRP: c_ulong = 0x5410; - -pub const TIOCGWINSZ: c_ulong = 0x5413; -pub const TIOCSWINSZ: c_ulong = 0x5414; diff --git a/src/header/termios/mod.rs b/src/header/termios/mod.rs index eb8978b564e1e97f8736ff6e3f43e4d17c4e8779..3172646f2b9552e82697c352314b669a4a3df35a 100644 --- a/src/header/termios/mod.rs +++ b/src/header/termios/mod.rs @@ -11,72 +11,6 @@ pub type tcflag_t = u32; pub const NCCS: usize = 32; -#[repr(C)] -#[derive(Default)] -pub struct termios { - c_iflag: tcflag_t, - c_oflag: tcflag_t, - c_cflag: tcflag_t, - c_lflag: tcflag_t, - c_line: cc_t, - c_cc: [cc_t; NCCS], - __c_ispeed: speed_t, - __c_ospeed: speed_t, -} - -#[no_mangle] -pub unsafe extern "C" fn tcgetattr(fd: c_int, out: *mut termios) -> c_int { - sys_ioctl::ioctl(fd, sys_ioctl::TCGETS, out as *mut c_void) -} - -#[no_mangle] -pub unsafe extern "C" fn tcsetattr(fd: c_int, act: c_int, value: *mut termios) -> c_int { - if act < 0 || act > 2 { - platform::errno = errno::EINVAL; - return -1; - } - // This is safe because ioctl shouldn't modify the value - sys_ioctl::ioctl(fd, sys_ioctl::TCSETS + act as c_ulong, value as *mut c_void) -} - -#[no_mangle] -pub unsafe extern "C" fn cfgetispeed(termios_p: *const termios) -> speed_t { - (*termios_p).__c_ispeed -} - -#[no_mangle] -pub unsafe extern "C" fn cfgetospeed(termios_p: *const termios) -> speed_t { - (*termios_p).__c_ospeed -} - -#[no_mangle] -pub unsafe extern "C" fn cfsetispeed(termios_p: *mut termios, speed: speed_t) -> c_int { - match speed as usize { - B0..=B38400 | B57600..=B4000000 => { - (*termios_p).__c_ispeed = speed; - 0 - } - _ => { - platform::errno = errno::EINVAL; - -1 - } - } -} - -#[no_mangle] -pub unsafe extern "C" fn cfsetospeed(termios_p: *mut termios, speed: speed_t) -> c_int { - match speed as usize { - B0..=B38400 | B57600..=B4000000 => { - (*termios_p).__c_ospeed = speed; - 0 - } - _ => { - platform::errno = errno::EINVAL; - -1 - } - } -} - pub const VINTR: usize = 0; pub const VQUIT: usize = 1; pub const VERASE: usize = 2; @@ -191,3 +125,74 @@ pub const TCIOFLUSH: usize = 2; pub const TCSANOW: usize = 0; pub const TCSADRAIN: usize = 1; pub const TCSAFLUSH: usize = 2; + +#[repr(C)] +#[derive(Default)] +pub struct termios { + c_iflag: tcflag_t, + c_oflag: tcflag_t, + c_cflag: tcflag_t, + c_lflag: tcflag_t, + c_line: cc_t, + c_cc: [cc_t; NCCS], + __c_ispeed: speed_t, + __c_ospeed: speed_t, +} + +#[no_mangle] +pub unsafe extern "C" fn tcgetattr(fd: c_int, out: *mut termios) -> c_int { + sys_ioctl::ioctl(fd, sys_ioctl::TCGETS, out as *mut c_void) +} + +#[no_mangle] +pub unsafe extern "C" fn tcsetattr(fd: c_int, act: c_int, value: *mut termios) -> c_int { + if act < 0 || act > 2 { + platform::errno = errno::EINVAL; + return -1; + } + // This is safe because ioctl shouldn't modify the value + sys_ioctl::ioctl(fd, sys_ioctl::TCSETS + act as c_ulong, value as *mut c_void) +} + +#[no_mangle] +pub unsafe extern "C" fn cfgetispeed(termios_p: *const termios) -> speed_t { + (*termios_p).__c_ispeed +} + +#[no_mangle] +pub unsafe extern "C" fn cfgetospeed(termios_p: *const termios) -> speed_t { + (*termios_p).__c_ospeed +} + +#[no_mangle] +pub unsafe extern "C" fn cfsetispeed(termios_p: *mut termios, speed: speed_t) -> c_int { + match speed as usize { + B0..=B38400 | B57600..=B4000000 => { + (*termios_p).__c_ispeed = speed; + 0 + } + _ => { + platform::errno = errno::EINVAL; + -1 + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn cfsetospeed(termios_p: *mut termios, speed: speed_t) -> c_int { + match speed as usize { + B0..=B38400 | B57600..=B4000000 => { + (*termios_p).__c_ospeed = speed; + 0 + } + _ => { + platform::errno = errno::EINVAL; + -1 + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn tcflush(fd: c_int, queue: c_int) -> c_int { + sys_ioctl::ioctl(fd, sys_ioctl::TCFLSH, queue as *mut c_void) +}