Cleanup termios and ioctls and add tcflush
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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 termios = &mut *(out as *mut termios::termios);
|
||||
if e(dup_read(fd, "termios", termios)) == !0 {
|
||||
-1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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 pgrp = &mut *(out as *mut pid_t);
|
||||
if e(dup_read(fd, "pgrp", pgrp)) == !0 {
|
||||
-1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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 winsize = &mut *(out as *mut winsize);
|
||||
if e(dup_read(fd, "winsize", winsize)) == !0 {
|
||||
-1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
||||
+71
-66
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user