代码之家  ›  专栏  ›  技术社区  ›  devgirl05

read(2)在哪里检查termios结构以确定它应该以(非)阻塞的方式读取STDIN?

  •  0
  • devgirl05  · 技术社区  · 3 周前

    我搜索过:

    • 标准库(认为答案不存在,因为libchidden_def有一个死胡同,它显然是连接到内核的东西)
    • xfce4终端源代码
    • Linux内核

    并且仍然未能找到解释read(2)如何知道必须阻止或不阻止的答案。是的,读(2)不是包含答案的函数,但它是起点。

    在这里,我将绘制问题的时间线:

    1. tcsetattr(设置VMIN和VTIME以获得原始模式或其他组合)
    2. 读取(尝试从STDIN读取)
    3. ???
    4. 某个地方检查我们设置的termios结构,并决定是否继续轮询STDIN,直到换行符出现,直到x个字符在里面,直到x时间过去,或者总是返回里面的内容
    5. 我们得到read()的结果
    1 回复  |  直到 3 周前
        1
  •  3
  •   KamilCuk    3 周前

    read(2)在哪里检查termios结构以确定它应该以(非)阻塞的方式读取STDIN?

    在Linux内核中TTY的实现。相关文件 https://docs.kernel.org/driver-api/tty/index.html .

    首先,我们需要来自的宏 https://elixir.bootlin.com/linux/latest/source/include/linux/tty.h#L40 :

    #define TIME_CHAR(tty) ((tty)->termios.c_cc[VTIME])
    #define MIN_CHAR(tty) ((tty)->termios.c_cc[VMIN])
    

    看起来这里使用了VMIN和VTIME https://elixir.bootlin.com/linux/latest/source/drivers/tty/n_tty.c#L2212 :

        minimum = time = 0;
        timeout = MAX_SCHEDULE_TIMEOUT;
        if (!ldata->icanon) {
            minimum = MIN_CHAR(tty);
            if (minimum) {
                time = (HZ / 10) * TIME_CHAR(tty);
            } else {
                timeout = (HZ / 10) * TIME_CHAR(tty);
                minimum = 1;
            }
        }
        ......
                    timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
                            timeout);
    
        ......
        if (kb - kbuf >= minimum)
            break;
        if (time)
            timeout = time;