为什么使用 termios->c_cflag |= PARENB 调用 tcsetattr() 会返回 -1 且 errno 为 EINVAL?

问题描述 投票:0回答:1

我正在学习 Linux TTY。还有一个现象让我无法理解:

PARENB
设置为
c_cflag
tcsetattr()
将返回 -1,errno 为 EINVAL。
为什么PARENB会导致EINVAL?哪里返回-1.

我在 Linux 内核源代码 (linux-5.15.30) 上使用 GDB 检查了这一点,我注意到

tty_ioctl
返回 0,而不是 -1。
那么C lib会返回-1吗?我也尝试在 glibc 源代码中检查它,但在我看来,我没有发现任何地方可以返回 -1。

PARENB 的意思是:“启用输出奇偶校验生成和输入奇偶校验检查。”
我可以理解有些 TTY 不支持它。但是系统如何知道它不受支持,即使 linux 内核

tty_ioctl()
返回 0?

我的测试代码是:

#include <stdio.h>
#include <pty.h>
#include <termios.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char *argv[])
{
        int ret = 0;
        int m = 0;
        int s = 0;

        struct termios t;

        ret = openpty(&m, &s, NULL, NULL, NULL);
        if (0 != ret) {
                printf("Error: openpty failed\n");
                return -1;
        }

        tcgetattr(s, &t);
        printf("> termios->c_cflag = %#x\n", t.c_cflag);

        t.c_cflag |= PARENB;
        printf(">>> will tcsetattr(), c_cflag = %#x, TCSETS = %d, TCSANOW = %d\n",
                        t.c_cflag, TCSETS, TCSANOW);
        ret = tcsetattr(s, TCSANOW, &t);
        if (0 != ret) {
                printf("Error: tcsetattr failed, ret = %d, errno = %d\n", ret, errno);
        }

        close(m);
        close(s);
        return 0;
}

结果是:

gcc test_attr.c -lutil
./a.out
> termios->c_cflag = 0xbf
>>> will tcsetattr(), c_cflag = 0x1bf, TCSETS = 21506, TCSANOW = 0
Error: tcsetattr failed, ret = -1, errno = 22

我想知道哪里返回-1,它怎么知道

PARENB
不受支持。

linux linux-kernel posix tty pty
1个回答
0
投票

如果禁用非 POSIX 特殊字符,它似乎可以工作:

t.c_lflag &= ~(IEXTEN);
© www.soinside.com 2019 - 2024. All rights reserved.