carveone
carveone

Reputation: 909

Pseudo tty set to canonical is not canonical

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

Answers (1)

carveone
carveone

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

Related Questions