Reputation: 909
I'm writing a simple emulator for a serial device using a pseudo tty (under Linux). The program that writes to the serial device, writes to the slave side while the emulator (this program) is on the master side.
I create the usual master/slave pair with:
posix_openpt
grantpt
unlockpt
I then create a soft link in /tmp/emulator to whatever ptsname returns. A minor issue is that when the slave closes, select returns and read() returns EIO. Which is somewhat annoying so I open ptsname myself to prevent this (I do the same with pipes usually).
I use tcsetattr to set ICANON on the master side so I (should) read a line at a time. The protocol is line based.
So far so good. Except it doesn't work as expected. If send a single byte to the slave side of the PTY, the select() returns and read() reads that one byte. That's not canonical at all! It's supposed to wait until a \n is received!
I will test with an actual serial port and an Arduino to see if this happens there too.
Upvotes: 1
Views: 305
Reputation: 909
This appears to be expected behaviour. My experiments show that, when icanon is set:
Open /dev/pty/x:
write() bytes, 1 at a time ---> each appears on master immediately
Master end
write() bytes, 1 at a time ---> does NOT appear on /dev/pty/x slave until \n
In other words, the slave end, the one at /dev/pty/x is acting like a terminal. All the operations like disabling the echo, setting the line mode, translating cr and lf etc or canonical mode are available.
The master side is not a terminal. It just permits sending and receiving data to/from the slave side.
This is what pty(7) is saying but you have to read between the lines to realise that the master does not also act like a terminal.
Upvotes: 0