C:设置伪终端并使用xterm打开
以下简化的代码段由后台的线程执行。 该线程一直运行,直到他被告知退出(通过用户输入)。
在下面的代码中,我删除了一些错误检查以获得更好的可读性。 即使进行错误检查,代码也能很好地工作,并且创建和/或打开主设备和从设备。
... int master, slave; char *slavename; char *cc; master = posix_openpt(O_RDWR); grantpt(master); unlockpt(master); slavename = ptsname(master); slave = open(slavename, O_RDWR); printf("master: %d\n",master); printf("slavename: %s\n",slavename);
在我的机器上输出如下:
master: 3 slavename: /dev/pts/4
所以我认为在程序运行时用命令xterm -S4/3
(4 = pt-slave,3 = pt-master)打开一个xterm应该为创建的伪终端打开一个新的xterm窗口。 但xterm只是开始运行而没有给出错误或任何进一步的信息,但根本没有打开一个窗口。 有什么建议吗?
编辑:
现在有了Wumpus Q.Wumbley的帮助xterm正常启动,但我无法将任何输出重定向到它。 我试过了:
dup2(slave, 1); dup2(slave, 2); printf("Some test message\n");
用fopen
然后使用fprinf
fopen
fprinf
。 两者都没用。
xterm进程需要以某种方式访问文件描述符。 此function的预期用途可能是将xterm作为创建pty的子进程启动。 不过还有其他方法。 你可以使用SCM_RIGHTS文件描述符传递(非常复杂), 或者,如果你有一个Linux风格的 /proc
文件系统,试试这个:
xterm -S4/3 3<>/proc/$PID_OF_YOUR_OTHER_PROGRAM/fd/3
‘你可能以前见过shell重定向操作符: <
for stdin, >
stdout, 2>
stderr(文件描述符2)。 也许您还看到其他文件描述符正在输入或输出,例如3
。 那么3<>
运算符就是另一个运算符。 它以读/写模式打开文件描述符3。 而/proc/PID/fd/NUM
是访问另一个进程打开的文件的便捷方式。
我不知道其余的问题。 我之前没有尝试过使用这种xterm模式。
好吧, /proc
的伎俩是个坏主意。 它等同于/dev/ptmx
的新开放,创建了一个新的无关pty。
你将不得不让xterm成为你的pty创建程序的孩子。
这是我用来探索该function的测试程序。 它很草率,但它揭示了一些有趣的东西。 一个有趣的事情是xterm在成功初始化后将其窗口ID写入pty主服务器。 这是你需要处理的事情。 它在实际用户输入开始之前显示为tty上的一行输入。
另一件有趣的事情是,如果使用-S/dev/pts/2/3
,xterm(至少Debian中的版本)会崩溃,尽管在手册页中特别提到它是一种允许的格式。
#include #include #include #include #include int main(void) { int master; char *slavename, window[64], buf[64]; FILE *slave; master = posix_openpt(O_RDWR); grantpt(master); unlockpt(master); slavename = ptsname(master); printf("master: %d\n", master); printf("slavename: %s\n", slavename); snprintf(buf, sizeof buf, "-S%s/%d", strrchr(slavename,'/')+1, master); if(!fork()) { execlp("xterm", "xterm", buf, (char *)0); _exit(1); } slave = fopen(slavename, "r+"); fgets(window, sizeof window, slave); printf("window: %s\n", window); fputs("say something: ", slave); fgets(buf, sizeof buf, slave); fprintf(slave, "you said %s\nexiting in 3 seconds...\n", buf); sleep(3); return 0; }