Fix TCGETS/TCSETS using wrong termios type definition
This commit is contained in:
parent
79bacb8bf4
commit
f65bbdd924
@ -26,11 +26,31 @@ pub struct IfReq {
|
|||||||
pub ifr_union: [u8; 24],
|
pub ifr_union: [u8; 24],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The termios structure used in the Linux kernel is not the same as we use in the glibc. Thus, we have two
|
||||||
|
definitions here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const KERNEL_NCCS: usize = 19;
|
||||||
|
const NCCS: usize = 32;
|
||||||
|
|
||||||
type TcflagT = u32;
|
type TcflagT = u32;
|
||||||
type CcT = u8;
|
type CcT = u8;
|
||||||
type SpeedT = u32;
|
type SpeedT = u32;
|
||||||
const NCCS: usize = 32;
|
|
||||||
#[derive(Debug)]
|
// Corresponds to the definition in glibc: sysdeps/unix/sysv/linux/kernel_termios.h
|
||||||
|
#[derive(Debug, Default, Copy, Clone)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct KernelTermios {
|
||||||
|
pub c_iflag: TcflagT,
|
||||||
|
pub c_oflag: TcflagT,
|
||||||
|
pub c_cflag: TcflagT,
|
||||||
|
pub c_lflag: TcflagT,
|
||||||
|
pub c_line: CcT,
|
||||||
|
pub c_cc: [CcT; KERNEL_NCCS],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Copy, Clone)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Termios {
|
pub struct Termios {
|
||||||
pub c_iflag: TcflagT,
|
pub c_iflag: TcflagT,
|
||||||
@ -42,3 +62,75 @@ pub struct Termios {
|
|||||||
pub c_ispeed: SpeedT,
|
pub c_ispeed: SpeedT,
|
||||||
pub c_ospeed: SpeedT,
|
pub c_ospeed: SpeedT,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl KernelTermios {
|
||||||
|
fn to_termios(&self) -> Termios {
|
||||||
|
let mut c_cc = [0; NCCS];
|
||||||
|
c_cc[..KERNEL_NCCS].copy_from_slice(&self.c_cc);
|
||||||
|
Termios {
|
||||||
|
c_iflag: self.c_iflag,
|
||||||
|
c_oflag: self.c_oflag,
|
||||||
|
c_cflag: self.c_cflag,
|
||||||
|
c_lflag: self.c_lflag,
|
||||||
|
c_line: self.c_line,
|
||||||
|
c_cc: c_cc,
|
||||||
|
c_ispeed: 0,
|
||||||
|
c_ospeed: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn execute_tcgets(&mut self, host_fd: i32, cmd_num: i32) -> Result<i32> {
|
||||||
|
debug_assert!(cmd_num == 0x5401);
|
||||||
|
let mut termios = self.to_termios();
|
||||||
|
let len = std::mem::size_of::<Termios>();
|
||||||
|
let ret = try_libc!({
|
||||||
|
let mut retval: i32 = 0;
|
||||||
|
let status = occlum_ocall_ioctl(
|
||||||
|
&mut retval as *mut i32,
|
||||||
|
host_fd,
|
||||||
|
cmd_num,
|
||||||
|
&mut termios as *const Termios as *mut c_void,
|
||||||
|
len,
|
||||||
|
);
|
||||||
|
assert!(status == sgx_status_t::SGX_SUCCESS);
|
||||||
|
retval
|
||||||
|
});
|
||||||
|
*self = termios.to_kernel_termios();
|
||||||
|
Ok(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn execute_tcsets(&self, host_fd: i32, cmd_num: i32) -> Result<i32> {
|
||||||
|
debug_assert!(cmd_num == 0x5402);
|
||||||
|
let termios = self.to_termios();
|
||||||
|
let len = std::mem::size_of::<Termios>();
|
||||||
|
let ret = try_libc!({
|
||||||
|
let mut retval: i32 = 0;
|
||||||
|
let status = occlum_ocall_ioctl(
|
||||||
|
&mut retval as *mut i32,
|
||||||
|
host_fd,
|
||||||
|
cmd_num,
|
||||||
|
&termios as *const Termios as *mut c_void,
|
||||||
|
len,
|
||||||
|
);
|
||||||
|
assert!(status == sgx_status_t::SGX_SUCCESS);
|
||||||
|
retval
|
||||||
|
});
|
||||||
|
Ok(ret)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Termios {
|
||||||
|
pub fn to_kernel_termios(&self) -> KernelTermios {
|
||||||
|
let mut c_cc = [0; KERNEL_NCCS];
|
||||||
|
c_cc.copy_from_slice(&self.c_cc[..KERNEL_NCCS]);
|
||||||
|
|
||||||
|
KernelTermios {
|
||||||
|
c_iflag: self.c_iflag,
|
||||||
|
c_oflag: self.c_oflag,
|
||||||
|
c_cflag: self.c_cflag,
|
||||||
|
c_lflag: self.c_lflag,
|
||||||
|
c_line: self.c_line,
|
||||||
|
c_cc: c_cc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -27,8 +27,8 @@ impl_ioctl_nums_and_cmds! {
|
|||||||
// ioctl_name => (ioctl_num, ioctl_type_arg)
|
// ioctl_name => (ioctl_num, ioctl_type_arg)
|
||||||
|
|
||||||
// Get terminal attributes
|
// Get terminal attributes
|
||||||
TCGETS => (0x5401, mut Termios), // ignore
|
TCGETS => (0x5401, mut KernelTermios), // ignore
|
||||||
TCSETS => (0x5402, Termios),
|
TCSETS => (0x5402, KernelTermios),
|
||||||
// Get window size
|
// Get window size
|
||||||
TIOCGWINSZ => (0x5413, mut WinSize),
|
TIOCGWINSZ => (0x5413, mut WinSize),
|
||||||
// Set window size
|
// Set window size
|
||||||
|
@ -170,9 +170,22 @@ impl File for StdoutFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ioctl(&self, cmd: &mut IoctlCmd) -> Result<i32> {
|
fn ioctl(&self, cmd: &mut IoctlCmd) -> Result<i32> {
|
||||||
|
let host_stdout_fd = self.host_fd() as i32;
|
||||||
|
let cmd_bits = cmd.cmd_num() as c_int;
|
||||||
|
|
||||||
|
// Handle special case for TCGETS/TCSETS which use different structures
|
||||||
|
// in linux kernel and libc
|
||||||
|
match cmd {
|
||||||
|
IoctlCmd::TCGETS(kernel_termios) => {
|
||||||
|
return kernel_termios.execute_tcgets(host_stdout_fd, cmd_bits);
|
||||||
|
}
|
||||||
|
IoctlCmd::TCSETS(kernel_termios) => {
|
||||||
|
return kernel_termios.execute_tcsets(host_stdout_fd, cmd_bits);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
|
||||||
let can_delegate_to_host = match cmd {
|
let can_delegate_to_host = match cmd {
|
||||||
IoctlCmd::TCGETS(_) => true,
|
|
||||||
IoctlCmd::TCSETS(_) => true,
|
|
||||||
IoctlCmd::TIOCGWINSZ(_) => true,
|
IoctlCmd::TIOCGWINSZ(_) => true,
|
||||||
IoctlCmd::TIOCSWINSZ(_) => true,
|
IoctlCmd::TIOCSWINSZ(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
@ -181,9 +194,7 @@ impl File for StdoutFile {
|
|||||||
return_errno!(EINVAL, "unknown ioctl cmd for stdout");
|
return_errno!(EINVAL, "unknown ioctl cmd for stdout");
|
||||||
}
|
}
|
||||||
|
|
||||||
let cmd_bits = cmd.cmd_num() as c_int;
|
|
||||||
let cmd_arg_ptr = cmd.arg_ptr() as *mut c_void;
|
let cmd_arg_ptr = cmd.arg_ptr() as *mut c_void;
|
||||||
let host_stdout_fd = self.host_fd() as i32;
|
|
||||||
let cmd_arg_len = cmd.arg_len();
|
let cmd_arg_len = cmd.arg_len();
|
||||||
let ret = try_libc!({
|
let ret = try_libc!({
|
||||||
let mut retval: i32 = 0;
|
let mut retval: i32 = 0;
|
||||||
@ -321,9 +332,22 @@ impl File for StdinFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ioctl(&self, cmd: &mut IoctlCmd) -> Result<i32> {
|
fn ioctl(&self, cmd: &mut IoctlCmd) -> Result<i32> {
|
||||||
|
let host_stdin_fd = self.host_fd() as i32;
|
||||||
|
let cmd_bits = cmd.cmd_num() as c_int;
|
||||||
|
|
||||||
|
// Handle special case for TCGETS/TCSETS which use different structures
|
||||||
|
// in linux kernel and libc
|
||||||
|
match cmd {
|
||||||
|
IoctlCmd::TCGETS(kernel_termios) => {
|
||||||
|
return kernel_termios.execute_tcgets(host_stdin_fd, cmd_bits);
|
||||||
|
}
|
||||||
|
IoctlCmd::TCSETS(kernel_termios) => {
|
||||||
|
return kernel_termios.execute_tcsets(host_stdin_fd, cmd_bits);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
|
||||||
let can_delegate_to_host = match cmd {
|
let can_delegate_to_host = match cmd {
|
||||||
IoctlCmd::TCGETS(_) => true,
|
|
||||||
IoctlCmd::TCSETS(_) => true,
|
|
||||||
IoctlCmd::TIOCGWINSZ(_) => true,
|
IoctlCmd::TIOCGWINSZ(_) => true,
|
||||||
IoctlCmd::TIOCSWINSZ(_) => true,
|
IoctlCmd::TIOCSWINSZ(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
@ -332,9 +356,7 @@ impl File for StdinFile {
|
|||||||
return_errno!(EINVAL, "unknown ioctl cmd for stdin");
|
return_errno!(EINVAL, "unknown ioctl cmd for stdin");
|
||||||
}
|
}
|
||||||
|
|
||||||
let cmd_bits = cmd.cmd_num() as c_int;
|
|
||||||
let cmd_arg_ptr = cmd.arg_ptr() as *mut c_void;
|
let cmd_arg_ptr = cmd.arg_ptr() as *mut c_void;
|
||||||
let host_stdin_fd = self.host_fd() as i32;
|
|
||||||
let cmd_arg_len = cmd.arg_len();
|
let cmd_arg_len = cmd.arg_len();
|
||||||
let ret = try_libc!({
|
let ret = try_libc!({
|
||||||
let mut retval: i32 = 0;
|
let mut retval: i32 = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user