Han*_*Lub 30 c unix portability freebsd pty
我编写并维护了一个程序rlwrap,它使用伪终端与子进程通信. 在所有Unix(类似)系统中都可以找到伪终端(ptys),但它们在不同平台上的表现略有不同.
例证:在rlwrap,父进程保持slave pty打开以密切关注子进程的终端设置(在Linux和FreeBSD上可以使用master,例如在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;
}
Run Code Online (Sandbox Code Playgroud)
父进程将按预期回显子进程的输出,但是当我省略close(slave)(保持打开状态rlwrap)时:
这种行为是否记录在某处?有没有理由呢?我可以在不关闭父进程中的奴隶的情况下绕过它吗?
我发现不让奴隶成为一个控制终端 - 用login_tty一些简单的dup()电话取代电话 - 将解决问题.rlwrap然而,这不是解决方案:相当多的命令需要控制终端(/dev/tty)来与之通信,因此rlwrap必须为它们提供一个.
在 FreeBSD 10-STABLE 上我确实得到了两条输出线。
(您可以替换openptyand fork,基本上也forkpty可以解决问题。)login_tty
在 FreeBSD 8.0 中,旧的pty(4)驱动程序被替换为pts(4). 新的pty(4)行为与旧的不同。来自手册;
与以前的实现不同,当 PTY 变得不使用时,主设备节点和从设备节点将被销毁。在不存在的主设备上调用 stat(2) 将导致创建新的主设备节点。主设备只能通过打开和关闭来破坏。
8.0-RELEASE 和 10.0-RELEASE 之间很可能存在重大变化
您可能还想查看FreeBSD ports 树中应用的补丁。
| 归档时间: |
|
| 查看次数: |
1622 次 |
| 最近记录: |