Нет вывода из нестандартного файлового дескриптора

Нет вывода из нестандартного файлового дескриптора

18.01.2020 11:49:52 Просмотров 20 Источник

У меня возникли проблемы с получением данных из дочернего процесса.

Чтобы отправить строку дочернему процессу, вы пишете в FD3, и он выводит результат в FD4.

Дочерний процесс работает нормально,и если бы он не мог писать в FD4, процесс не запустился бы правильно, поэтому FD4должен быть доступен, но я просто не знаю, почему не выводится.

Мои первоначальные мысли при отправке строки (в FD3) это не был нулевой байт, заканчивающийся, следовательно, не получая строку правильно (а затем не отправляя ничего обратно на FD4), но я уверен, что делаю это правильно.

Я протестировал запись в FD4в дочернем процессе вручную,и родитель получает вывод.

use nix::fcntl::FcntlArg::{F_SETFD};
use nix::fcntl::{fcntl, open, FdFlag, OFlag};
use nix::sys::socket::{socketpair, AddressFamily, SockFlag, SockType};
use nix::sys::stat::Mode;
use nix::unistd::{close, dup2, execvp, fork, pipe, read, write, ForkResult};
use std::ffi::CString;
use std::os::unix::io::RawFd;
use std::process::abort;

fn main() {
    let input_socket: (RawFd, RawFd) = create_socket();
    let output_socket: (RawFd, RawFd) = create_socket();

    match fork() {
        Ok(ForkResult::Parent { child, .. }) => {
            println!("Child PID: {}", child);

            close(input_socket.1).unwrap();
            close(output_socket.1).unwrap();

            let test = r#"{"id":0,"method":"Target.getTargets"}\0"#;
            write(input_socket.0, test.as_bytes()).expect("unable to write");

            let mut buf = [0; 64];
            read(output_socket.0, &mut buf).unwrap();
            println!("BUFFER: {:#?}", std::str::from_utf8(&buf).unwrap());
        }
        Ok(ForkResult::Child) => {
            setup_child(input_socket.1, output_socket.1);
            abort()
        }
        Err(err) => { println!("{}", err); abort()},
    }
}

#[cfg(any(
    target_os = "android",
    target_os = "dragonfly",
    target_os = "emscripten",
    target_os = "freebsd",
    target_os = "linux",
    target_os = "netbsd",
    target_os = "openbsd"
))]
fn create_socket() -> (RawFd, RawFd) {
    socketpair(
        AddressFamily::Unix,
        SockType::Stream,
        None,
        SockFlag::SOCK_CLOEXEC,
    )
    .unwrap()
}

#[cfg(any(target_os = "ios", target_os = "macos"))]
fn create_socket() -> (RawFd, RawFd) {
    let socket = socketpair(
        AddressFamily::Unix,
        SockType::Stream,
        None,
        SockFlag::empty(),
    )
    .unwrap();
    fcntl(socket.0, F_SETFD(FdFlag::FD_CLOEXEC)).unwrap();
    fcntl(socket.1, F_SETFD(FdFlag::FD_CLOEXEC)).unwrap();
    socket
}

fn setup_child(input: RawFd, output: RawFd) {
    let _input: RawFd = dup2(input, 3).unwrap();
    let _output: RawFd = dup2(output, 4).unwrap();

    let file = CString::new("/Applications/Google Chrome.app/Contents/MacOS/Google Chrome").unwrap();

    let arg1 = CString::new("--remote-debugging-pipe").unwrap();
    let arg2 = CString::new("--enable-logging=stderr").unwrap();
    let args = vec![arg1.as_c_str(),arg2.as_c_str()];

    let _res = execvp(&file, &args).unwrap();
}

Это открытый FDs для дочернего процесса: lsof -p 14620

COMMAND PID  USER   FD     TYPE DEVICE                  SIZE/OFF                  NODE NAME
Chrome 14620 tom    0      PIPE 0xcafab653bf79be56      16384                     ->0xfc41206e43b6bb9d
Chrome 14620 tom    1      PIPE 0x71c3c6a8bffbf5ad      16384                     ->0x587f975b5bfd4499
Chrome 14620 tom    2      PIPE 0x71c3c6a8bffbf5ad      16384                     ->0x587f975b5bfd4499
Chrome 14620 tom    3u     unix 0x36cd3ac44c49d68d        0t0                     ->0x36cd3ac44c49f2ad
Chrome 14620 tom    4u     unix 0x36cd3ac44c49dc05        0t0                     ->0x36cd3ac44c49f9b5

ОБНОВЛЕНИЕ

Я нашел проблему, по какой-то причине первый аргумент при запуске процесса chrome был проигнорирован?? Поэтому, когда я помещаю любой другой аргумент в качестве первого в списке, chrome фактически запускает удаленную отладку. Странный вопрос!

Когда я запускаю процесс chrome в терминале с --remote-debugging-pipeв качестве первого аргумента, он тоже работает нормально, так почему же это происходит, когда я использую: execvp(&file, &args)

У вопроса есть решение - Посмотреть?

Ответы - Нет вывода из нестандартного файлового дескриптора / No output from non standard File Descriptor

Является ответом!
James

19.01.2020 06:23:12

Проблема в том, как я запускаю процесс.

execvp(&file, &args)требует, чтобы первая arg была расположением файла. Спасибо: источник

Изменение этого кода заставляет все работать как ожидалось:

let args = vec![file.as_c_str(), arg1.as_c_str(),arg2.as_c_str()];
Закрыть X