#rust #pipe #file-descriptor #stdio
#Ржавчина #канал #файловый дескриптор #stdio
Вопрос:
Моя главная цель — реализовать программу в Rust для локального перенаправления stdio по каналам и похожа на это
- Программа выполняет команду «sh» и создает каналы между родительским процессом и дочерним процессом
- Выходные данные дочернего процесса передаются через канал (в данном случае приглашение) родительскому процессу
- Я набираю что-то на своем терминале, например «pwd», и это передается в канал дочернему процессу
- Дочерний процесс выполняет команду и отправляет выходные данные обратно через канал родительскому процессу и отображает текущий рабочий каталог на моем терминале
В конце концов, моя цель — заставить родительский процесс действовать как прокси-сервер и пересылать этот ввод-вывод через TLS-соединение между удаленным экземпляром ncat и дочерним процессом. На данный момент я пытаюсь правильно выполнить часть трубопровода.
Как мне это сделать? Мой текущий фрагмент кода выглядит следующим образом, но я не уверен, правильно ли я понял часть перенаправления, поскольку я не вижу подсказки.
let message_string = String::from("fd_pipe");
let message = message_string.as_ptr() as *const c_void;
let mut command_output = std::process::Command::new("/bin/sh")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("cannot execute command");
let command_stdin = command_output.stdin.unwrap();
println!("command_stdin {}", command_stdin.as_raw_fd());
let command_stdout = command_output.stdout.unwrap();
println!("command_stdout {}", command_stdout.as_raw_fd());
let command_stderr = command_output.stderr.unwrap();
println!("command_stderr {}", command_stderr.as_raw_fd());
nix::unistd::dup2(tokio::io::stdin().as_raw_fd(), command_stdin.as_raw_fd());
nix::unistd::dup2(tokio::io::stdout().as_raw_fd(), command_stdout.as_raw_fd());
nix::unistd::dup2(tokio::io::stderr().as_raw_fd(), command_stderr.as_raw_fd());
РЕДАКТИРОВАТЬ 2 ноября 2020
Кто-то на форуме Rust любезно предоставил мне решение (https://users.rust-lang.org/t/redirect-stdio-pipes-and-file-descriptors/50751/8 ), я подумал, что поделюсь этим и здесь
let mut command_output = std::process::Command::new("/bin/sh")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("cannot execute command");
let mut command_stdin = command_output.stdin.unwrap();
println!("command_stdin {}", command_stdin.as_raw_fd());
let copy_stdin_thread = std::thread::spawn(move || {
io::copy(amp;mut io::stdin(), amp;mut command_stdin)
});
let mut command_stdout = command_output.stdout.unwrap();
println!("command_stdout {}", command_stdout.as_raw_fd());
let copy_stdout_thread = std::thread::spawn(move || {
io::copy(amp;mut command_stdout, amp;mut io::stdout())
});
let command_stderr = command_output.stderr.unwrap();
println!("command_stderr {}", command_stderr.as_raw_fd());
let copy_stderr_thread = std::thread::spawn(move || {
io::copy(amp;mut command_stderr, amp;mut io::stderr())
});
copy_stdin_thread.join().unwrap()?;
copy_stdout_thread.join().unwrap()?;
copy_stderr_thread.join().unwrap()?;
Мой следующий вопрос: как мне связать перенаправленный stdio через TLS-соединение с удаленным прослушивателем ncat?
Комментарии:
1. Вам не нужно ничего дублировать, я думаю, все, что вам не хватает
command_output.wait()
. Можете ли вы уточнить, что не работает? Также.spawn()
подразумеваетStdio::piped()
, что они не нужны,Command::new("sh").spawn().unwrap().wait().unwrap()
если прокси-сервер работает нормально.2. Привет @kmdreko, спасибо за совет. Я также опубликовал решение, которым кто-то еще любезно поделился со мной.