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

При чтении больше чем одного процесса из последовательного устройства (/dev/ttyXX) делает его так, чтобы оба процесса не могли получить все данные - данные будут разделены между ними в некотором роде. Я хотел бы записать программу, которая читает из последовательного устройства, создает несколько основных/ведомых пар имущества и затем позволяет программы, которые были сделаны читать из последовательного устройства, чтобы вместо этого читать из имуществ так, чтобы все процессы считывания получили данные из последовательного устройства и имели действие имуществ как последовательное устройство в том смысле, что, когда они начинают читать из имущества, они получают только новые данные. Другими словами, Вы не получите данных, которые были записаны, прежде чем Вы начали читать (это - мой опыт, который это - то, как/dev/ttyXX устройства работают, или по крайней мере анемометр RS-232, который я читаю из). Именованные каналы могут подражать им семантика путем захвата SIGPIPE, чтобы решить, что нет никакого читателя, и таким образом мы можем принять решение не записать в тот конкретный именованный канал. Однако некоторые двоичные файлы, которые были записаны для использования терминалов, могут перестать работать, когда говорящий с именованными каналами, поскольку проверки на isatty () и errno условие на вызовах как tcsetattr () могут вызвать провальные условия. Ключ здесь должен смочь использовать существующие двоичные файлы, которые были записаны для терминала.

Так, если я могу обнаружить, когда ведомая сторона имущества открыта для чтения, это должно дать мне примерно ту же семантику, как там являющуюся никаким SIGPIPE в случае именованного канала. Я замечаю, что HP-UX имеет TIOCTRAP как ioctl () команда, которая, кажется, делает точно, что я хочу, но печально это не доступно на Linux.

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

Так, для разъяснения:
- Вопрос: Как я могу обнаружить, когда кто-то открывает ведомую сторону имущества (псевдотерминал) в Linux?
- Я хочу, чтобы читатель, открывающий ведомую сторону имущества, получил данные, записанные строго после того, как читатель открывает имущество (если моя мультизапись просто запишет данные некоторое время, прежде чем читатель откроет ведомую сторону, данные буферизуют, и в конечном счете устройство записи заблокируется, и ведомый читатель, после открытия, сразу получит все буферизированные данные - это не желательно, поскольку я хочу, чтобы это получило только данные, сгенерированные в непосредственной временной близости),
- Это должно быть имущество, не именованный канал, сокет, и т.д., как isatty () и tcsetattr (), и т.д. должен быть в порядке так, чтобы работали существующие двоичные файлы

10
задан Nate Sanders 15 August 2010 в 06:42
поделиться

1 ответ

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

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

Это устанавливает флаг HUP на ведущем устройстве 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 () в вашем источнике данных, а затем, когда data доступен, одновременно poll () все ваши главные ttys и отправка данных на любой из них, для которого не задано POLLHUP .

11
ответ дан 3 December 2019 в 23:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: