通过 termios 编程伪终端通信。奇偶校验位选项不起作用

Programming pseudo terminals communication by termios. Parity bit option doesn't works

我需要使用串行端口进行聊天。我通过 socat 模拟 pty:

socat -d -d PTY PTY

接下来我写了一个小demo。这就是我初始化 termios 结构的方式:

    int tty_fd = open(argv[1], O_RDWR | O_NONBLOCK);
    struct termios tio;
    bzero(&tio, sizeof(tio));
    // Frame bus runs at 38,400 BAUD
    const int BAUD_Rate = B38400;

    cfsetispeed(&tio, BAUD_Rate);
    cfsetospeed(&tio, BAUD_Rate);

    // Initialize to raw mode. PARMRK and PARENB will be over-ridden before calling tcsetattr()
    cfmakeraw(&tio);

    // Ignore modem lines and enable receiver and set bit per byte
    tio.c_cflag |= CLOCAL | CREAD | CS8;

    // NOTE: The following block overrides PARMRK and PARENB bits cleared by cfmakeraw.
    tio.c_cflag |=  PARENB;         // Enable even parity generation
    tio.c_iflag |=  INPCK;          // Enable parity checking
    tio.c_iflag |=  PARMRK;         // Enable in-band marking 
    tio.c_iflag &= ~IGNPAR;         // Make sure input parity errors are not ignored
    if (is_odd) 
            tio.c_cflag |= PARODD;
    tcsetattr(tty_fd, TCSANOW, &tio);

接下来我的整个演示列表:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h> 

struct termios init(int);

int main(int argc,char** argv)
{
        struct termios tio;
        char c = 0;
        int tty_fd = open(argv[1], O_RDWR | O_NONBLOCK);

        tio = init(strcmp(argv[3], "odd"));

        if (tcsetattr(tty_fd, TCSANOW, &tio) == -1)
        {
                printf("Failed to setup the port");
                return -1;
        }

        if (strcmp(argv[2], "write") == 0)
        {
                while (c != 'q')
                {
                        scanf("%c", &c);
                        write(tty_fd, &c, 1);
                }
        }
        if (strcmp(argv[2], "read") == 0)
        {
                while (c != 'q')
                {
                        if (read(tty_fd, &c, 1) > 0)
                                printf("%c", c);
                }
        }
        close(tty_fd);
}

struct termios init(int is_odd)
{
        struct termios tio;
        bzero(&tio, sizeof(tio));
        // Frame bus runs at 38,400 BAUD
        const int BAUD_Rate = B38400;

        cfsetispeed(&tio, BAUD_Rate);
        cfsetospeed(&tio, BAUD_Rate);

        // Initialize to raw mode. PARMRK and PARENB will be over-ridden before calling tcsetattr()
        cfmakeraw(&tio);

        // Ignore modem lines and enable receiver and set bit per byte
        tio.c_cflag |= CLOCAL | CREAD | CS8;

        // NOTE: The following block overrides PARMRK and PARENB bits cleared by cfmakeraw.
        tio.c_cflag |=  PARENB;         // Enable even parity generation
        tio.c_iflag |=  INPCK;          // Enable parity checking
        tio.c_iflag |=  PARMRK;         // Enable in-band marking 
        tio.c_iflag &= ~IGNPAR;         // Make sure input parity errors are not ignored
        if (is_odd == 0) 
                tio.c_cflag |= PARODD;
        return tio;
}

当我以 reader 身份启动一个应用程序,并以相似的奇偶校验方式启动另一个应用程序时,一切正常。但是当我尝试测试奇偶校验位设置时,我以不同的奇偶校验位启动它们,一切正常。所有消息发送无误。
是因为使用了伪终端,而不是真正的 COM 端口吗?
或者也许我创建一个 pty 的方式?

我的搭档也尝试使用 python 进行类似的测试,也有类似的结果。我使用 Linux Mint 17.3。

感谢您的回放。

我已阅读 pty 的手册页,发现伪终端根本不支持 termios 的 c_cflag 标志。