Use unsafe blocks in pty.h implementation
This commit is contained in:
+25
-16
@@ -1,3 +1,6 @@
|
||||
// TODO: set this for entire crate when possible
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use crate::{
|
||||
header::{fcntl, sys_ioctl, unistd},
|
||||
io::{Cursor, Write},
|
||||
@@ -6,28 +9,32 @@ use crate::{
|
||||
|
||||
pub(super) unsafe fn openpty(name: &mut [u8]) -> Result<(c_int, c_int), ()> {
|
||||
//TODO: wrap in auto-close struct
|
||||
let master = fcntl::open(c"/dev/ptmx".as_ptr(), fcntl::O_RDWR | fcntl::O_NOCTTY, 0);
|
||||
let master = unsafe { fcntl::open(c"/dev/ptmx".as_ptr(), fcntl::O_RDWR | fcntl::O_NOCTTY, 0) };
|
||||
if master < 0 {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let mut lock: c_int = 0;
|
||||
if sys_ioctl::ioctl(
|
||||
master,
|
||||
sys_ioctl::TIOCSPTLCK,
|
||||
&mut lock as *mut c_int as *mut c_void,
|
||||
) != 0
|
||||
if unsafe {
|
||||
sys_ioctl::ioctl(
|
||||
master,
|
||||
sys_ioctl::TIOCSPTLCK,
|
||||
&mut lock as *mut c_int as *mut c_void,
|
||||
)
|
||||
} != 0
|
||||
{
|
||||
unistd::close(master);
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let mut ptn: c_int = 0;
|
||||
if sys_ioctl::ioctl(
|
||||
master,
|
||||
sys_ioctl::TIOCGPTN,
|
||||
&mut ptn as *mut c_int as *mut c_void,
|
||||
) != 0
|
||||
if unsafe {
|
||||
sys_ioctl::ioctl(
|
||||
master,
|
||||
sys_ioctl::TIOCGPTN,
|
||||
&mut ptn as *mut c_int as *mut c_void,
|
||||
)
|
||||
} != 0
|
||||
{
|
||||
unistd::close(master);
|
||||
return Err(());
|
||||
@@ -36,11 +43,13 @@ pub(super) unsafe fn openpty(name: &mut [u8]) -> Result<(c_int, c_int), ()> {
|
||||
let mut cursor = Cursor::new(name);
|
||||
write!(cursor, "/dev/pts/{}\0", ptn);
|
||||
|
||||
let slave = fcntl::open(
|
||||
cursor.get_ref().as_ptr() as *const c_char,
|
||||
fcntl::O_RDWR | fcntl::O_NOCTTY,
|
||||
0,
|
||||
);
|
||||
let slave = unsafe {
|
||||
fcntl::open(
|
||||
cursor.get_ref().as_ptr() as *const c_char,
|
||||
fcntl::O_RDWR | fcntl::O_NOCTTY,
|
||||
0,
|
||||
)
|
||||
};
|
||||
if slave < 0 {
|
||||
unistd::close(master);
|
||||
return Err(());
|
||||
|
||||
+36
-29
@@ -2,6 +2,9 @@
|
||||
//!
|
||||
//! Non-POSIX, see <https://www.man7.org/linux/man-pages/man3/openpty.3.html>.
|
||||
|
||||
// TODO: set this for entire crate when possible
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use core::{mem, ptr, slice};
|
||||
|
||||
use crate::{
|
||||
@@ -31,26 +34,26 @@ pub unsafe extern "C" fn openpty(
|
||||
) -> c_int {
|
||||
let mut tmp_name = [0; limits::PATH_MAX];
|
||||
let name = if !namep.is_null() {
|
||||
slice::from_raw_parts_mut(namep as *mut u8, limits::PATH_MAX)
|
||||
unsafe { slice::from_raw_parts_mut(namep as *mut u8, limits::PATH_MAX) }
|
||||
} else {
|
||||
&mut tmp_name
|
||||
};
|
||||
|
||||
let (master, slave) = match imp::openpty(name) {
|
||||
let (master, slave) = match unsafe { imp::openpty(name) } {
|
||||
Ok(ok) => ok,
|
||||
Err(()) => return -1,
|
||||
};
|
||||
|
||||
if !termp.is_null() {
|
||||
termios::tcsetattr(slave, termios::TCSANOW, termp);
|
||||
unsafe { termios::tcsetattr(slave, termios::TCSANOW, termp) };
|
||||
}
|
||||
|
||||
if !winp.is_null() {
|
||||
sys_ioctl::ioctl(slave, sys_ioctl::TIOCSWINSZ, winp as *mut c_void);
|
||||
unsafe { sys_ioctl::ioctl(slave, sys_ioctl::TIOCSWINSZ, winp as *mut c_void) };
|
||||
}
|
||||
|
||||
*amaster = master;
|
||||
*aslave = slave;
|
||||
unsafe { *amaster = master };
|
||||
unsafe { *aslave = slave };
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -72,57 +75,61 @@ pub unsafe extern "C" fn forkpty(
|
||||
let mut set = signal::sigset_t::default();
|
||||
let mut oldset = signal::sigset_t::default();
|
||||
|
||||
if openpty(&mut m, &mut s, name, tio, ws) < 0 {
|
||||
if unsafe { openpty(&mut m, &mut s, name, tio, ws) } < 0 {
|
||||
return -1;
|
||||
}
|
||||
|
||||
signal::sigfillset(&mut set);
|
||||
signal::pthread_sigmask(signal::SIG_BLOCK, &mut set, &mut oldset);
|
||||
pthread::pthread_setcancelstate(pthread::PTHREAD_CANCEL_DISABLE, &mut cs);
|
||||
unsafe { signal::sigfillset(&mut set) };
|
||||
unsafe { signal::pthread_sigmask(signal::SIG_BLOCK, &mut set, &mut oldset) };
|
||||
unsafe { pthread::pthread_setcancelstate(pthread::PTHREAD_CANCEL_DISABLE, &mut cs) };
|
||||
|
||||
if unistd::pipe2(p.as_mut_ptr(), fcntl::O_CLOEXEC) != 0 {
|
||||
if unsafe { unistd::pipe2(p.as_mut_ptr(), fcntl::O_CLOEXEC) } != 0 {
|
||||
unistd::close(s);
|
||||
} else {
|
||||
pid = unistd::fork();
|
||||
pid = unsafe { unistd::fork() };
|
||||
if pid == 0 {
|
||||
unistd::close(m);
|
||||
unistd::close(p[0]);
|
||||
if utmp::login_tty(s) != 0 {
|
||||
unistd::write(
|
||||
p[1],
|
||||
platform::ERRNO.as_ptr().cast(),
|
||||
mem::size_of_val(&platform::ERRNO),
|
||||
);
|
||||
if unsafe { utmp::login_tty(s) } != 0 {
|
||||
unsafe {
|
||||
unistd::write(
|
||||
p[1],
|
||||
platform::ERRNO.as_ptr().cast(),
|
||||
mem::size_of_val(&platform::ERRNO),
|
||||
)
|
||||
};
|
||||
unistd::_exit(127);
|
||||
}
|
||||
unistd::close(p[1]);
|
||||
pthread::pthread_setcancelstate(cs, ptr::null_mut());
|
||||
signal::pthread_sigmask(signal::SIG_SETMASK, &mut oldset, ptr::null_mut());
|
||||
unsafe { pthread::pthread_setcancelstate(cs, ptr::null_mut()) };
|
||||
unsafe { signal::pthread_sigmask(signal::SIG_SETMASK, &mut oldset, ptr::null_mut()) };
|
||||
return 0;
|
||||
}
|
||||
|
||||
unistd::close(s);
|
||||
unistd::close(p[1]);
|
||||
|
||||
if unistd::read(
|
||||
p[0],
|
||||
&mut ec as *mut c_int as *mut c_void,
|
||||
mem::size_of::<c_int>(),
|
||||
) > 0
|
||||
if unsafe {
|
||||
unistd::read(
|
||||
p[0],
|
||||
&mut ec as *mut c_int as *mut c_void,
|
||||
mem::size_of::<c_int>(),
|
||||
)
|
||||
} > 0
|
||||
{
|
||||
let mut status = 0;
|
||||
sys_wait::waitpid(pid, &mut status, 0);
|
||||
unsafe { sys_wait::waitpid(pid, &mut status, 0) };
|
||||
pid = -1;
|
||||
platform::ERRNO.set(ec);
|
||||
}
|
||||
unistd::close(p[0]);
|
||||
}
|
||||
if pid > 0 {
|
||||
*pm = m;
|
||||
unsafe { *pm = m };
|
||||
} else {
|
||||
unistd::close(m);
|
||||
}
|
||||
pthread::pthread_setcancelstate(cs, ptr::null_mut());
|
||||
signal::pthread_sigmask(signal::SIG_SETMASK, &mut oldset, ptr::null_mut());
|
||||
unsafe { pthread::pthread_setcancelstate(cs, ptr::null_mut()) };
|
||||
unsafe { signal::pthread_sigmask(signal::SIG_SETMASK, &mut oldset, ptr::null_mut()) };
|
||||
pid
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user