您可以将mut i8转换为i32吗?

时间:2020-02-21 10:13:42

标签: unix casting rust pty

我正在尝试构建一个小型终端仿真器,并与libc遇到一些有趣的类型冲突。当我尝试建立pty连接的从属部分时,我需要使用对ptsname()的系统调用来创建从属,以便获取pts的名称,以便我可以访问它。但是,我收到一个类型错误,说libc :: ptsname()需要输入一个i32。这与说应该将其传递给文件描述符的手册页直接冲突。我只是想知道是否可以将文件描述符所具有的libc :: 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`.

1 个答案:

答案 0 :(得分:1)

并不是说它需要i32 input ,而是您要问ptsname(master as i32);的类型为i32。这可能有点令人困惑,因为c_inti32的别名,因此听起来像是在要求一个不相关的类型。

问题在于,当slave返回c_int时,您将ptsname的类型设为*mut c_charc_char也是别名, i8