gpt4 book ai didi

c - 如果未在父级中关闭,则从属 pty 上的最终输出将丢失。为什么?

转载 作者:太空狗 更新时间:2023-10-29 16:22:52 28 4
gpt4 key购买 nike

我编写并维护了一个程序 rlwrap它使用伪终端与子进程通信。 Pseudo-terminals (ptys) 存在于所有 Unix(类)系统中,但它们在不同平台上的行为略有不同。

恰当的例子:在 rlwrap 中,父进程使从 pty 保持打开状态以密切关注子进程的终端设置(在 Linux 和 FreeBSD 上可以使用主进程,但在 Solaris 中不行, 例如)

在 FreeBSD (8.2)(但不是 Linux)上,这会导致子进程的最终输出丢失。例如:

#include <stdio.h>

/* save as test.c and compile with gcc -o test test.c -lutil */

#define BUFSIZE 255

int main(void) {
int master, slave;
char buf[BUFSIZE];
int nread;

openpty(&master, &slave, NULL, NULL, NULL);

if (fork()) { /* parent: */
close(slave); /* leave this out and lose slave's final words ... WHY? */
do {
nread = read(master, buf, BUFSIZE);
write(STDOUT_FILENO, buf, nread); /* echo child's output to stdout */
} while (nread > 0);
} else { /* child: */
login_tty(slave); /* this makes child a session leader and slave a controlling */
/* terminal for it, then dup()s std{in,out,err} to slave */
printf("Feeling OK :-)\n");
sleep(1);
printf("Feeling unwell ... Arghhh!\n"); /* this line may get lost */
}
return 0;
}

父进程将按预期回显子进程的输出,但是当我省略 close(slave) 时(保持打开状态,就像在 rlwrap 中一样):

  • 在 FreeBSD 上,父级看不到最终输出行,而是读取 EOF。 (如果有的话,我会预料到相反的情况——保持从端打开会防止输出丢失)
  • 另一方面,在 Linux 上,从不看到 EOF,甚至 child 死后也看不到(无论我们是否关闭 slave)

是否在某处记录了此行为?有理由吗?在父进程中不关闭slave可以绕过吗?

我发现让从设备成为控制终端——用一些简单的dup()调用替换login_tty调用——将解决问题。然而,这不是 rlwrap 的解决方案:相当多的命令需要一个控制终端 (/dev/tty) 进行通信,因此 rlwrap 有为他们提供一个。

最佳答案

我认为 Pty 有独特的独立行为。

  1. 如果最后一个数据被写入,系统终止
  2. 如果 child 退出(破管?),系统终止

代码依赖于存在足够长的管道来发送数据,但是退出的子进程可能导致虚拟 channel 在接收到数据之前被删除。

这对于 Pty 来说是独一无二的,对于真正的终端来说是不存在的。

关于c - 如果未在父级中关闭,则从属 pty 上的最终输出将丢失。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23458160/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com