Мастер псевдотерминала читает только что написанное - PullRequest
9 голосов
/ 19 мая 2011

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

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

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

Пример:

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

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

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

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

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

Ответы [ 2 ]

4 голосов
/ 24 января 2012

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

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)
3 голосов
/ 10 октября 2017

В случае, если кто-то найдет этот вопрос и ответ 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)
...