【问题标题】:TERMIOS: What is the OFILL flag in c_oflag used for?TERMIOS:c_oflag 中的 OFILL 标志是做什么用的?
【发布时间】:2013-11-03 16:23:30
【问题描述】:

问题一:termios_p->c_oflag中的OFILL标志是干什么用的。

文档是这样说的:

延迟发送填充字符,而不是使用定时延迟。

为了解决这个问题,我创建了这个小测试程序:

#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <termios.h>

int main(int argc, char *argv[])
{

    char c;
    int res;
    struct termios termios_old, termios_new;

    res = tcgetattr(0, &termios_old);
    assert(res == 0);
    termios_new = termios_old;

    // Setup the terminal in raw mode
    termios_new.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP |
                             INLCR | IGNCR | ICRNL | IXON);
    termios_new.c_oflag &= ~OPOST;
    termios_new.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    termios_new.c_cflag &= ~(CSIZE | PARENB);
    termios_new.c_cflag |= CS8;

    // Add the flag I'm trying to understand
    termios_new.c_oflag |= OFILL;  // What is this flag used for?


    res = tcsetattr(0, TCSANOW, &termios_new);
    assert(res == 0);

    while (1) {
        read(0, &c, 1);
        printf("0x%x %d\r\n", (int)c, (int)c);

        if (c == 'q')
            break;
    }

    tcsetattr(0, TCSANOW, &termios_old);
    return 0;
}

当我运行程序时,如果设置或未设置标志,我看不到任何差异......我希望这个标志可以以某种方式更容易检测是否按下了 ESC 键。

在上面的程序中,如果我按下Left-Arrow-key 并且如果我按下序列:ESC[D,我会看到完全相同的输出。

问题2:我应该如何检测用户是否按下了ESC按钮以及我应该如何检测用户是否按下了`左箭头按钮

由于这是学习终端 IO 系统如何工作的练习,所以我不想使用任何库。

【问题讨论】:

  • 我认为您可能会将 termios 的延迟与您的终端添加延迟来进行字符转义混淆。

标签: linux terminal termios


【解决方案1】:

OFILL 标志的使用与您发布的文档所说的非常相似 - 不是等待某个定时延迟,而是发送一些填充字节。这有时会在高速 uart 上完成,因为与发送两个填充字节所需的时间相比,定时延迟确实很长,并且双方都能够以接近全速的速度运行。

对于您的示例,如果 stdin 没有理由向您发送延迟,则可能不会,因此这可以解释您的程序没有看到任何填充字节。由于这是一个发送端选项,我不确定您是否可以让标准输入发出填充字节。

我还会查看 NLDLY/NL0/NL1,它们可以触发发送填充字节,但我不确定这些会如何影响标准输入/标准输出。

【讨论】:

  • 当我按下ECS 键时,我看到应用程序接收任何输入之前会有延迟(约 1 秒)。
  • 不,我没有找到这个问题,但它看起来很有趣,谢谢。设置 escape-time 0 时,我正在徘徊 tmux 的作用
猜你喜欢
  • 2011-03-21
  • 2021-08-30
  • 2018-09-18
  • 1970-01-01
  • 1970-01-01
  • 2010-09-05
  • 2021-08-29
  • 1970-01-01
相关资源
最近更新 更多