Как имитировать TTY, одновременно передавая stdio?

#shell #terminal #rust #tty #pty

#оболочка #терминал #Ржавчина #tty #pty

Вопрос:

Я ищу кроссплатформенное решение для имитации TTY (PTY?) В Rust, Одновременно передавая stdio.

Интерфейс основан на веб-технологиях, где отображается интерактивный терминал. Пользователи могут запускать команды, и все их входные данные будут отправляться на серверную часть Rust, где команды выполняются. Std {in, out, err} отправляются в обратном направлении, чтобы обеспечить интерактивный опыт.

Вот упрощенный пример (только стандартный вывод):

 let mut child = Command::new(command)
    .stdout(Stdio::piped())
    .spawn()
    .expect("Command failed to start");

loop {
    let read = reader.read(amp;mut chunk);

    if let Ok(len) = read {
        if len == 0 {
            break;
        }
        let chunk = amp;chunk[..len];

        send_chunk(chunk); // send chunk to frontend
    } else {
        eprintln!("Err: {}", read.unwrap_err());
    }
}
  

В настоящее время при выполнении команды tty выводится: not a tty , но в идеале она должна выводить имя файла (например /dev/ttys002 ). И программы, такие как atty, должны возвращаться true .

Запуск только серверной части в терминале с унаследованным stdio работает, но тогда я не могу отправить stdio обратно во внешний интерфейс.

Ответ №1:

Определите «кросс-платформенный». Что касается PTYs, это псевдо-устройства, поддерживаемые ядром, в комплекте с ioctls и всем остальным. На самом деле многое из того, что должен будет сделать ваш эмулятор терминала, — это реализация принимающей стороны этих ioctls.

Пока вы работаете на компьютере с BSD API (который включает Linux), лучшим способом действий было бы openpty использовать это. Если вы хотите быть переносимым на системы, не поддерживающие BSD PTY, вам придется подключить функции tty в дочернем процессе (предварительно загрузив вспомогательную библиотеку).

Комментарии:

1. Я хотел бы поддерживать Linux, Mac OS, Windows. Поддержка BSD PTY на данный момент в порядке. Возможно, поддержка Windows может быть достигнута с помощью ConPTY ?

2. Я также пытаюсь создать пользовательское приглашение, возможно ли это или эти ioctls также объединяют приглашение?

3. @MartonLanga: приглашение является частью оболочки. Просто запустите оболочку внутри вашего PTY, и все готово.

4. Я также пишу пользовательскую оболочку, так что, думаю, тогда я смогу позаботиться о приглашении вручную!