How to pass stdout in Rust

I’m trying to build a raw interface to a C library in Rust. The C example code passes stdout into a function at some point.

How do I port this to Rust? I mean, I know about std::io::stdout but I can’t pass this to a C function in place of the C equivalent.

1 Like

This is going to be tricky, because FILE * is a libc-specific thing.

There’s https://doc.rust-lang.org/std/os/unix/io/trait.AsRawFd.html that gives raw file descriptor, which then could be reopened with fdopen to get a new FILE *.

Alternatively, you could write a C function that does return stdout (compile it with the cc crate in your build.rs).

See also guide to making sys crates.

Hmm, that’s a surprise. I would have guessed someone had hit this before. Writing a function in C to return stdout seems the best way forward, but this is just to test my sys crate, so I guess I will have to try in another way.

Thanks for the advice.

If stdout is not a macro on your platform, you should just be able to do:

extern crate libc;

extern {
    static stdout: *mut libc::FILE;
}

fn main() {
    unsafe {
        libc::fwrite(b"test".as_ptr() as _, 5, 1, stdout);
    }
}
3 Likes

Be careful though, as this essentially takes ownership of the file descriptor:

http://man7.org/linux/man-pages/man3/fdopen.3.html

The file descriptor is not dup’ed, and will be closed when the stream created by fdopen() is closed.

1 Like