Мастер псевдотерминала читает только что написанное

Я работаю над проектом, который взаимодействует с «виртуальными устройствами» (процессы python), которые используют соединения последовательного порта с реальными устройствами, которые также используют последовательные порты, и я использую псевдотерминалы для подключения нескольких (более 2) из ​​этих последовательных портов коммуникационные процессы (моделирование последовательных устройств) вместе, и я столкнулся с небольшой загвоздкой.

У меня есть процесс python, который генерирует псевдотерминалы, символически связывает ведомый конец pty с файлом (чтобы процессы могли создавать pyserial объект для имени файла), в то время как главные концы сохраняются моим процессом генерации pty и читаются; когда данные поступают на один мастер, они регистрируются, а затем записываются на другие мастера. Этот подход работает, если процесс слушания присутствует всегда.

Проблема заключается в том, что виртуальное устройство умирает или никогда не запускается (что является допустимым вариантом использования для этого проекта). В моей системе кажется, что если данные записываются на главный конец pty, если нет ничего, слушающего подчиненный конец, вызов чтения на этом главном узле вернет данные, которые были только что записаны! Это означает, что устройства получают одни и те же данные более одного раза — это нехорошо!

Пример:

>>master, slave = pty.openpty()
>>os.write(master,"Hello!")
6
>>os.read(master,6)
'Hello!'

Я бы предпочел, чтобы вызов read() блокировался до тех пор, пока ведомое устройство не отправит данные. На самом деле это поведение ведомого устройства — оно может писать, а затем os.read(slave,1) будет блокироваться до тех пор, пока ведущее устройство не запишет данные.

Мои «виртуальные устройства» должны иметь возможность передавать имя файла, чтобы открыть объект последовательного порта; Я попытался создать символическую ссылку на главный конец, но это заставляет мои виртуальные устройства открывать /dev/ptmx, что создает новую пару псевдотерминалов вместо обратной ссылки на уже существующие подчиненные устройства!

Есть ли способ изменить поведение мастера? Или даже просто передать мастеру имя файла, соответствующее ведомому устройству (а не только /dev/ptmx)?

Заранее спасибо!


person bradreaves    schedule 19.05.2011    source источник


Ответы (2)


Я почти уверен, что это потому, что эхо включено по умолчанию. Чтобы позаимствовать документы из Python termios, вы можете сделать следующее:

master, slave = os.openpty()    # It's preferred to use os.openpty()
old_settings = termios.tcgetattr(master)
new_settings = termios.tcgetattr(master)   # Does this to avoid modifying a reference that also modifies old_settings
new_settings[3] = new_settings[3] & ~termios.ECHO
termios.tcsetattr(master, termios.TCSADRAIN, new_settings)

Вы можете использовать следующее, чтобы восстановить старые настройки:

termios.tcsetattr(master, termios.TCSADRAIN, old_settings)
person John Szakmeister    schedule 24.01.2012
comment
Я почти уверен, что это тоже так, но вы хотите отключить эхо на ведомой стороне. Помните, что ptys — это псевдотерминалы, а мастер подобен вашей клавиатуре/дисплею, а подчиненный — как устройство /dev/ttyxx, к которому оно подключено. ptys эмулирует всю обработку терминала, что здесь может оказаться бесполезным; В качестве альтернативы ОП может посмотреть, как работают FIFO. - person sienkiew; 24.05.2012

Если кто-то найдет этот вопрос, и ответ jszakmeister не работает, вот что сработало для меня.

openpty, кажется, создает pty в каноническом режиме с включенным эхом. Это не то, что можно было бы ожидать. Вы можете изменить режим с помощью функции tty.setraw, как в этом примере простого эхо-сервера openpty:

master, slave = os.openpty()
tty.setraw(master, termios.TCSANOW)
print("Connect to:", os.ttyname(slave))

while True:
    try:
        data = os.read(master, 10000)
    except OSError:
        break
    if not data:
        break
    os.write(master, data)
person Vasily G    schedule 10.10.2017
comment
Это очень странно. openpty создает главный/подчиненный pty — подчиненный является терминалом, а ведущий — нет. Мастер-сторона не читает каноническую и не обращает внимания на настройки IGNCR или INLCR и т. д. Но. Это эхо без ведомого, если вы не отключите это! Это не то, чего я ожидал. - person carveone; 04.11.2018