Я пытаюсь создать небольшой эмулятор терминала и сталкиваюсь с некоторыми интересными конфликтами типов с lib c. Когда я пытаюсь установить подчиненную часть pty-соединения, мне нужно создать подчиненное устройство с системным вызовом ptsname (), чтобы получить имя для pts, чтобы я мог получить к нему доступ. Тем не менее, я получаю ошибку типа, говорящую, что lib c :: ptsname () требует i32 для ввода. Это находится в прямом конфликте с man-страницей, в которой говорится, что необходимо передать дескриптор файла. Мне просто интересно, смогу ли я преобразовать lib c :: c_int, который у меня есть, для дескриптора файла в i32 для передачи в ptsname.
Код выглядит следующим образом:
use libc::{self, c_int, grantpt, posix_openpt, ptsname, unlockpt, O_RDWR};
use std::os::unix::io::FromRawFd;
use std::process::{Child, Command, Stdio};
#[derive(Debug)]
pub struct Pty {
process: Child,
fd: i32,
}
fn create_pty(process: &str) -> Pty {
let master: c_int;
unsafe {
// create master/slave pair of fd
master = posix_openpt(O_RDWR);
if master == -1 {
panic!("Failed to posix_openpt");
}
// set slave ownership and mode as master
let mut result = grantpt(master);
if result == -1 {
panic!("Failed to grantpt");
}
// unlock slave
result = unlockpt(master);
if result == -1 {
panic!("Failed to unlockpt");
}
}
let slave: c_int = ptsname(master as i32);
slave = libc::open(slave);
let mut builder = Command::new(process);
match builder.spawn() {
Ok(process) => {
let pty = Pty {
process,
fd: master,
};
pty
}
Err(e) => {
panic!("Failed to create pty: {}", e);
}
}
}
fn main() {
let shell = "/bin/bish";
let pty = create_pty(shell);
println!("{:?}", pty);
}
и вывод консоли (пока вторая ошибка может быть проигнорирована):
error[E0308]: mismatched types
--> src/main.rs:42:24
|
42 | let slave: c_int = ptsname(master as i32);
| ^^^^^^^^^^^^^^^^^^^^^^ expected i32, found *-ptr
|
= note: expected type `i32`
found type `*mut i8`
error[E0060]: this function takes at least 2 parameters but 1 parameter was supplied
--> src/main.rs:43:13
|
43 | slave = libc::open(slave);
| ^^^^^^^^^^^^^^^^^ expected at least 2 parameters
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0060, E0308.
For more information about an error, try `rustc --explain E0060`.
error: could not compile `experiment`.