【问题标题】:Change default file descriptor for Rust print functions更改 Rust 打印函数的默认文件描述符
【发布时间】:2021-02-12 15:13:07
【问题描述】:

我正在研究 Rust 并使用用 C++ 编写的共享库。 C++ 库产生一些线程的问题,这些线程不断地打印到 stdout (1) 并且干扰了我自己的日志记录。 我能够使用dup 将标准输出复制到 fd = 3。然后我打开一个管道 (4, 5),并使用 dup2 将旧标准输出移动到管道的一端。 结果:

  • C++ 库写入 fd = 1(旧标准输出),但这会转到另一个管道,在那里我可以在另一个线程中捕获数据(比如我从 fd = 5 读取数据)。然后我可以解析这些日志并将它们打印到控制台。
  • 在 Rust 代码中,我可以使用 libc::write 到 fd = 3,这将直接进入控制台。

现在的问题是标准的 Rust 函数,例如 println!仍会尝试写入 fd = 1,但我希望能够更改默认行为,因此 Rust 代码将写入 fd = 3 而不是 1,这样,任何与 Rust 打印相关的函数都将打印到控制台,共享库中的所有内容都将在单独的线程上解析。

在稳定的 Rust 中可以做到这一点吗?我发现最接近的是set_print 函数,它看起来很不稳定,我什至无法使用 +nightly build 来使用它。

【问题讨论】:

  • 可能不需要c++ 标签,因为这是一个 Rust 问题,而 C++ 只涉及到。
  • 最安全的选择可能是制作您自己的自定义 println 宏,只需将 args 重定向到 format 宏调用。
  • @Aplet123,确实,这就是我现在正在做的事情。在log4rs 之上使用带有写入器的附加程序,所以请登录!宏将写入与标准输出不同的 fd。但是简单地更改标准输出会容易得多。

标签: rust stdout ffi libc unsafe


【解决方案1】:

如果可以使用writeln! 而不是println!,您可以调用from_raw_fd 来打开一个合适的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!")?;
// ...

注意:from_raw_fd 是不安全的,因为您必须确保 File 承担文件描述符的唯一所有权,在这种情况下,没有其他人关闭或与文件描述符 3 交互。(但您可以使用 into_raw_fd在使用 File 时重新声明 fd 的所有权。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 2020-03-26
    相关资源
    最近更新 更多