1

I'm working on Rust and using a shared library written in C++. The problem that the C++ library spawns a few threads that constantly print to stdout (1) and that interferes with my own logging. I was able to duplicate stdout using dup to fd = 3. Then I open up a pipe (4, 5), and use dup2 to move old stdout to one end of the pipe. As a result:

  • C++ library writes to fd = 1 (old stdout), but that goes to another pipe where I can capture the data in another thread (say I read from fd = 5). Then I can parse those logs and print them to the console.
  • In Rust code I can use libc::write to fd = 3 and that will go directly to the console.

The problem now is that standard Rust function such as println! will still try to write to fd = 1, but I'd like to be able to change the default behavior so Rust code will write to fd = 3 instead of 1, that way, any Rust print related function will print to the console, and everything from the shared library will be parsed on a separate thread.

Is that possible to do in stable Rust? Closest thing I found is set_print function which looks like it's unstable and I couldn't even use it using +nightly build.

3
  • 1
    Probably don't need the c++ tag, since this is a Rust question and C++ is only tangentially involved. Commented Feb 12, 2021 at 15:21
  • 1
    The safest bet is probably to make your own custom println macro that simply redirects the args to a format macro call. Commented Feb 12, 2021 at 15:59
  • @Aplet123, indeed, that's what I'm doing right now. Using an appender with a writer on top of log4rs so log! macros will write to a different fd than stdout. But it will be much easier to simply change the stdout. Commented Feb 12, 2021 at 16:10

1 Answer 1

2

If it's acceptable to use writeln! instead of println!, you can call from_raw_fd to open a proper File:

use std::fs::File;
use std::io::{BufWriter, Write};
use std::os::unix::io::FromRawFd;

let mut out = BufWriter::new(unsafe { File::from_raw_fd(3) });
writeln!(out, "hello world!")?;
// ...

Note: from_raw_fd is unsafe because you must ensure that the File assumes sole ownership of the file descriptor, in this case that no one else closes or interacts with file descriptor 3. (But you can use into_raw_fd to re-assert ownership of the fd it while consuming the File.)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.