Как я могу обнаружить, когда кто-то открывает подчиненную сторону PTY (псевдо-) в Linux?

StackOverflow https://stackoverflow.com/questions/3486491

Вопрос

Имея более одного процесса, прочитанного с последовательного устройства (/ dev / ttyxx), так что оба процесса не могут получить все данные - данные будут разделены между ними. Я хотел бы написать программу, которая читает с последовательного устройства, создает несколько паре PTY Master / Plave, а затем позволяет программам, которые были сделаны для чтения с последовательного устройства, чтобы вместо этого прочитать от ptys, чтобы все процессы чтения получали данные С серийного устройства и у Ptys действуют как последовательное устройство в том смысле, что когда они начинают читать от Pty, они получают только самые последние данные. Другими словами, вы не получите никаких данных, которые были написаны, прежде чем вы начали читать (это мой опыт, что это как / dev / ttyxx устройства работают или, по меньшей мере, анемометр RS-232, который я читаю). Имированные трубы могут имитировать эту семантику, захватывая SIGPIPE, чтобы определить, что нет читателя, и поэтому мы можем выбрать не писать на эту конкретную названную трубу. Тем не менее, некоторые двоичные файлы, которые были написаны для использования терминалов, могут потерпеть неудачу при разговоре с именованными трубами, в качестве проверки для ISATTY () и условия Errno на звонках, такими как TCSETATTTR (), могут вызвать недостающие условия. Ключ здесь состоит в том, чтобы иметь возможность использовать существующие двоичные файлы, которые были написаны для терминала.

Итак, если я смогу обнаружить, когда подчиненная сторона PTY открыта для чтения, это должно приверить мне примерно одинаковую семантику, поскольку в названном футбольном случае нет SigPipe. Я замечаю, что HP-UX имеет Tioctrap в качестве команды IOCTL (), которая, похоже, именно то, что я хочу, но к сожалению, это не доступно в Linux.

Я читал ссылки на дни, и количество вариантов для этого типа вещь ошеломляющая. Ответ может лежать в настройках терминала, блокируя / неблокирующее поведение, настройка размеров буферов где-то, условия, от которых сообщается из опроса () / выбора () или некоторой комбинации. Однако я не могу найти ничего. Я задаюсь вопросом, возможно, что мне нужно написать свой собственный драйвер устройства, но кажется, что я должен быть в состоянии сделать это, не делая так далеко.

Итак, для разъяснений:
- Вопрос в том, как я могу обнаружить, когда кто-то открывает подчиненную сторону PTY (псевдо- клемма) в Linux?
- Я хочу, чтобы читатель открывал верульную сторону PTY, чтобы получать данные, написанные строго после того, как читатель открывает PTY (если мой мультиписный процесс только что записывает данные, прежде чем читатель открывает рабскую сторону, данные будут буферными и В конце концов писатель заблокирует и подчиненный читатель, при открытии, сразу получит все буферизованные данные - это не желательно, поскольку я хочу получить только данные, сгенерированные в непосредственной близости от вида)
- Это должен Быть PTY, а не названной трубой, розеткой и т. Д., как итация () и TCSetattr (), и т. Д. Необходимо в порядке, так что существующие двоичные файлы работают

Это было полезно?

Решение

Причина, по которой вы не можете найти это потому, что нет документированного интерфейса специально для этого. Тем не менее, есть трюк, который позволяет вам это сделать. После открытия Pseudo-Terminal Master (предполагается здесь, чтобы быть дескриптором файла ptm), вы открываете и сразу закрываете рабскую сторону:

close(open(ptsname(ptm), O_RDWR | O_NOCTTY));

Это устанавливает флаг HUP на Master Tty. Теперь вы регулярно опросайте флаг HUP с poll() (Скажем, всякий раз, когда данные входят из вашего источника данных):

struct pollfd pfd = { .fd = ptm, .events = POLLHUP };
poll(&pfd, 1, 10 /* or other small timeout */);

if (!(pfd.revents & POLLHUP))
{
    /* There is now a reader on the slave side */
}

Если читатель когда-либо уходит, POLLHUP будет установлен снова.

В вашем случае вам, вероятно, даже не нужно помнить с одного цикла к следующему, имеет ли данный PTY читатель - просто блок на read() В вашем источнике данных, то когда данные доступны, одновременно poll() все ваши мастеры Ttys и отправьте данные любую из них, которые не имеют POLLHUP набор.

Другие советы

Добавьте Inotify Watch на раб PTY и опросить на этом. Вы можете получить событие Inotify On Open. Затем вы можете опросить на дескрипторе файла INOTIFY и дескриптором файла Master Pty. Вы можете получить событие Inotify для Open (In_Open). Это разблокирует опрос, когда рабская сторона открыта.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top