Problem with NonBlockingReader::from_fd() with i32 argument

Problematic code line:

unsafe {
    let mut buffer: Vec<u8> = Vec::new();

    let mut fd = PORT_PAIR_HANDLES[cirquit].as_raw_fd();
    let mut noblock_stdout = NonBlockingReader::from_fd(fd).unwrap();    // Line 262

    let n: usize = noblock_stdout.read_available(&mut buffer).unwrap();

Maybe not so relevant, but my file handles was put into a vector
by code like:

    static mut PORT_PAIR_HANDLES: Vec<std::fs::File> = Vec::<std::fs::File>::new();
    .
    .
    .
          unsafe {
            if *fspec != "/dev/null" {
                let thefile = std::fs::OpenOptions::new()
                                .read(true)
                                .write(true)
                                .create(true)
                                .truncate(true)
                                .open(fspec);

                if thefile.is_ok() {
                    PORT_PAIR_IN_USE_FLAGS.push(true);
                    PORT_PAIR_HANDLES.push(thefile.unwrap());
    .
    .
    .

Cargo.toml file:

[package]
name = "rseqcore"
version = "0.2.0"
authors = ["Hans Davidsson"]
edition = "2018"

[lib]
crate-type = ["dylib"]  # The crate types to generate.
name = "rseqcore"       # The name of the target.
path = "src/lib.rs"     # The source file of the target.

[dependencies]
epoll = "4.3.1"
nonblock = "0.1.0"

I see that I still have epoll in my dependencies.
I did not succeed in having the epoll stuff working (I think it was a fight between me and the
compiler then also.
I can read and write blocking to my files, and I was also able to do non-blocking reads with
external code (in a dylib written in C), but it think I should write my whole lib in Rust instead of
splitting it in a Rust part and character device I/O in an external homemade .so or .a module.
I am running cargo using docker and the rust:1.44.0 image on a Raspberry Pi 3B+, but I also
have a similar toolchain for amd_64 architecture using Docker on Ubuntu 20.04.

As a beginner in the Rust domain, since about 6 weeks, (previous experience from C, Python, Assembler, Pascal, a little C++, ...), I feel that I should take some advice about how to win this
fight with Cargo and the Rust compiler.

Errors reported by cargo build for line 262 and 264:

error[E0277]: the trait bound `i32: std::io::Read` is not satisfied
   --> src/lib.rs:262:57
    |
262 |     let mut noblock_stdout = NonBlockingReader::from_fd(fd).unwrap();
    |                                                         ^^ the trait `std::io::Read` is not implemented for `i32`
    |
    = note: required by `nonblock::NonBlockingReader::<R>::from_fd`

error[E0277]: the trait bound `i32: std::os::unix::io::AsRawFd` is not satisfied
   --> src/lib.rs:262:57
    |
262 |     let mut noblock_stdout = NonBlockingReader::from_fd(fd).unwrap();
    |                                                         ^^ the trait `std::os::unix::io::AsRawFd` is not implemented for `i32`
    |
    = note: required by `nonblock::NonBlockingReader::<R>::from_fd`

error[E0277]: the trait bound `i32: std::io::Read` is not satisfied
   --> src/lib.rs:262:30
    |
262 |     let mut noblock_stdout = NonBlockingReader::from_fd(fd).unwrap();
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::io::Read` is not implemented for `i32`
    | 
   ::: /cargo_cache/registry/src/github.com-1ecc6299db9ec823/nonblock-0.1.0/src/lib.rs:29:43
    |
29  | pub struct NonBlockingReader<R: AsRawFd + Read> {
    |                                           ---- required by this bound in `nonblock::NonBlockingReader`

error[E0277]: the trait bound `i32: std::os::unix::io::AsRawFd` is not satisfied
   --> src/lib.rs:262:30
    |
262 |     let mut noblock_stdout = NonBlockingReader::from_fd(fd).unwrap();
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::os::unix::io::AsRawFd` is not implemented for `i32`
    | 
   ::: /cargo_cache/registry/src/github.com-1ecc6299db9ec823/nonblock-0.1.0/src/lib.rs:29:33
    |
29  | pub struct NonBlockingReader<R: AsRawFd + Read> {
    |                                 ------- required by this bound in `nonblock::NonBlockingReader`

error[E0599]: no method named `read_available` found for struct `nonblock::NonBlockingReader<i32>` in the current scope
   --> src/lib.rs:264:35
    |
264 |     let n: usize = noblock_stdout.read_available(&mut buffer).unwrap();
    |                                   ^^^^^^^^^^^^^^ method not found in `nonblock::NonBlockingReader<i32>`
    |
    = note: the method `read_available` exists but the following trait bounds were not satisfied:
            `i32: std::io::Read`
            `i32: std::os::unix::io::AsRawFd`

Warning summary:

warning: unused import: `std::io`
warning: unused import: `std::io::prelude::*`
warning: unused import: `std::fs::File`
warning: unused import: `std::io::Read`

I may upload more code (or more complete code) later, but
for now I can at least give an idea about what "use" directives
are, currently, in my lib.rs file:

$ fgrep use dest_dir_link/rust_seq_core/src/lib.rs | fgrep ::
// use epoll::Event;
use std::io::Write;
// use std::io::Read;
use std::io::Read;
use nonblock::NonBlockingReader;
use std::io::Read;
//use std::process::{Command, Stdio};
//use std::time::Duration;
use nonblock::NonBlockingReader;
use std::io;
use std::io::prelude::*;
use std::fs::File;
use std::os::unix::io::AsRawFd;
$

Thanks in advance!

Hans Davidsson harley42@gmail.com

Can you edit your post and wrap all code, file contents and error messages in back ticks like below? It makes it much easier to read.

```
Put code here
```

Thanks! Much easier to read. It looks like the issue is the from_fd method doesn’t actually take a raw fd directly but instead takes something that implements AsRawFd + Read. In this case you want to pass it the File object directly without calling as_raw_fd() yourself.

Thanks, but I am so new to Rust, that I seem to need even more detailed help. I am sorry for that !

I have created very short program that compiles with a new error message. It would be nice if you want to have a look at that too.

Cargo.toml:

[package]
name = "nonblock_test"
version = "0.0.1"
authors = ["Hans Davidsson <harley42@gmail.com>"]
edition = "2018"

[dependencies]
nonblock = "0.1.0"

src/main.rs:


use nonblock::NonBlockingReader;

static mut PORT_PAIR_HANDLES: Vec<std::fs::File> = Vec::<std::fs::File>::new();

fn fake_open_port_pair() {
    // unsafe {
    //     PORT_PAIR_HANDLES.push( .... );
    // }
}

fn main() {
    let mut noblock_stdout = NonBlockingReader(PORT_PAIR_HANDLES[0]);
    let mut buffer: Vec<u8> = Vec::new();
    let _n: usize = noblock_stdout.read_available(&mut buffer).unwrap();
}

Build error:

error[E0423]: expected function, tuple struct or tuple variant, found struct `NonBlockingReader`
  --> src/main.rs:13:30
   |
13 |     let mut noblock_stdout = NonBlockingReader(PORT_PAIR_HANDLES[0]);
   |                              ^^^^^^^^^^^^^^^^^ did you mean `NonBlockingReader { /* fields */ }`?

error: aborting due to previous error

Thanks in advance!

According to documentation, NonBlockingReader can't be created directly. You must use one of the functions listed there.

And to know what you can use, check the documentation for AsRawFd trait (link in the nonblock's documentation is broken - this crate is probably too old, and something in standard library had changed).

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.