子进程无法从创建的伪终端读取
问题描述:
我正在尝试编写一个应用程序,它可以通过使用伪终端以密码登录到SSH。但是,如果我将()写入主设备,那么数据不会在从设备中出现。这里有一个简单的测试用例:子进程无法从创建的伪终端读取
#include <sys/wait.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#ifdef __linux__
#include <pty.h>
#else
#include <util.h>
#endif
int
main() {
int master;
pid_t pid = forkpty(&master, NULL, NULL, NULL);
if (pid == 0) {
int ch;
read(0, &ch, 1);
_exit(1);
} else {
printf("Press Enter to send a byte.\n");
getchar();
write(master, "1", 1);
printf("Done. Waiting for process to exit...\n");
waitpid(pid, NULL, 0);
return 0;
}
}
该应用程序将首先输出“按Enter键发送一个字节”。按Enter后,我期望子进程的read()返回。但是read()似乎无限地阻塞,即使master的write()成功了,所以master在waitpid()上永远等待。这是怎么回事?
答
问题是你没有修改PTY的行纪律。默认的行规则是面向行的,所以在读取换行符之前,不会有任何输入发送到从属进程。 (您可以通过发送一个“\ n”给从机而不是“1”来看到这一点)。您可以在子进程中通过调用tcgetattr
,cfmakeraw
和tcsetattr
来运行PTY RAW模式,如下所示:
if (pid == 0) {
int ch;
struct termios t;
tcgetattr(0, &t);
cfmakeraw(&t);
tcsetattr(0, TCSANOW, &t);
read(0, &ch, 1);
_exit(1);
} else {
这似乎适用于我。
我不确定你在用什么,但是我会用'expect'这样的东西。它在大多数发行版上都可用。 http://expect.nist.gov/ – 2010-02-02 19:02:52
我正在编写的应用程序将分发给可能没有“期望”或可能不想安装它的用户。除此之外,我还想知道如何做伪终端,以防将来需要它们用于其他任何事情。 – Hongli 2010-02-02 19:08:34
试试这个:写(master,“1 \ n”,2); – sambowry 2010-02-02 19:25:36