【发布时间】:2017-01-09 15:31:39
【问题描述】:
我有一个在linux C上运行的伪终端,打开如图:
else
{
struct termios slave_orig_term_settings; // Saved terminal settings
struct termios new_term_settings; // Current terminal settings
// CHILD
close(fdm);
rc = tcgetattr(fds, &slave_orig_term_settings);
new_term_settings = slave_orig_term_settings;
new_term_settings.c_cc[VEOF] = '|';
new_term_settings.c_oflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ISIG | ICRNL);
cfmakeraw (&new_term_settings);
tcsetattr (fds, TCSANOW, &new_term_settings);
}
当从管道读取时,我可以创建一个非阻塞的 read(),它会在例如 5 秒后返回。问题是,如果我执行像“ls”这样的命令,它会在几毫秒内返回,它会在返回前等待整整 5 秒。
我理解使用物理 GUI 终端,而不是像这样的伪终端,用户可以按 CTRL^D 并在每个输出结束时发送 EOF。
我想要这个效果,所以我的程序可以说“好的,我收到了这个特定的字节,这意味着终端已经完成了输出,我现在可以将这个输出返回给调用者,我知道没有更多的了输出读取”。
我知道这是通过 termios() 函数(或者它是包装器 stty)完成的,但我无法让它工作。我希望终端向我发送“|”输出完成后使用 char 而不是 ctrl^d (\x04),但它不起作用。
为了清楚起见,在完成输出后(通过 read()),我想接收 '|'字节。所以如果我发送“pwd”命令,我会得到这个输出:
$ pwd
/home/user/dir
$|
有人可以告诉我如何编辑此代码以实现该效果吗?
感谢您的帮助。
编辑 - 选择()代码
while ( (bytes = select(pipe + 1, &fd_in, NULL, NULL, &tv)) )
{
if (FD_ISSET(pipe, &fd_in))
{
read (pipe...)
上述代码的行为正如我所描述的,等待 tv 的完整值,即使管道上没有任何内容,然后返回。
【问题讨论】:
-
.c_cc[VEOF]特殊字符仅用于“规范”模式(ICANON位在.c_lflags中设置),但cfmakeraw设置为“原始”模式(ICANON位未设置)。