The pseudo-terminal master reads what he just wrote

I am working on a project that interacts with “virtual devices” (python processes) that use serial port connections with real devices that also use serial ports, and I use pseudo-terms to connect several (more than two) of these serial port communication processes (simulation of serial devices) together, and I hit a little.

I have a python process that generates pseudo-terminals, symbolizes the slave end of pty for a file (so processes can create a pyserial object for a file name), while the wizard ends with my process of generating pty and reading; when data arrives at one master, data is recorded and then written to other masters. This approach works if the listening process always exists.

The problem is that the virtual device dies or never starts (which is a valid use case for this project). On my system, it seems that if data is being written to the main end of pty, if there is nothing that listens to the end of the slave, a call read on that host will return the data just written! This means that devices receive the same data more than once - not good!

Example:

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

I would prefer the read () call to block until the subordinate sends the data. In fact, this is the behavior of the slave - it can be written, and then os.read (slave, 1) will be blocked until the master writes data.

My "virtual devices" should be able to pass the file name to open the serial port object; I tried to symbolize the main end, but this forces my virtual devices to open / dev / ptmx, which creates a new pseudo-terminal pair instead of referring to slaves that already exist!

Is there a way to change the behavior of the wizard? Or even just get the file name of the wizard that matches the slave (and not just / dev / ptmx)?

Thanks in advance!

+7
source share
2 answers

I am sure this is because echo is enabled by default. To borrow from Python termios docs you can do:

 master, slave = os.openpty() # It 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) 

To restore the old settings, you can use the following:

 termios.tcsetattr(master, termios.TCSADRAIN, old_settings) 
+4
source

If someone finds this question and the jszakmeister answer doesn't work, this is what worked for me.

openpty It seems pty is being created in canonical mode with echo enabled. This is not what one would expect. You can change the mode using the tty.setraw function, as in this example of a simple openpty relay server:

 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) 
+1
source

All Articles