下面的简化代码是由后台线程执行的。该线程一直运行,直到被告知退出(通过用户输入)。
在下面的代码中,我删除了一些错误检查以提高可读性。即使进行错误检查,代码也能正常工作,并且主设备和从设备都被创建和/或打开。
...
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
。两者都不起作用。
最佳答案
xterm 进程需要以某种方式访问文件描述符。此功能的预期用途可能是将 xterm 作为创建 pty 的子进程启动。不过,还有其他方法。您可以使用 SCM_RIGHTS 文件描述符传递(相当复杂),或者,如果您有 Linux 风格的 /proc
文件系统试试这个:
xterm -S4/3 3<>/proc/$PID_OF_YOUR_OTHER_PROGRAM/fd/3
'
您以前可能见过 shell 重定向运算符: <
对于标准输入,>
对于标准输出,2>
对于 stderr(文件描述符 2)。也许您还看到其他文件描述符被打开以进行输入或输出,例如 3<inputfile 4>outputfile
。嗯3<>
这里的运算符是另一个。它以读/写模式打开文件描述符 3。和/proc/PID/fd/NUM
是访问另一个进程打开的文件的便捷方法。
我不知道问题的其余部分。我以前没有尝试过使用 xterm 的这种模式。
好的,/proc
的技巧这是一个坏主意。相当于重新打开/dev/ptmx
,创建一个新的不相关的 pty。
您必须将 xterm 作为您的 pty 创建程序的子项。
这是我用来探索该功能的测试程序。虽然很草率,但它揭示了一些有趣的事情。一件有趣的事情是 xterm 在成功初始化后将其窗口 ID 写入 pty master。这是你需要处理的事情。在实际用户输入开始之前,它在 tty 上显示为一行输入。
另一个有趣的事情是,如果您使用 -S/dev/pts/2/3
,xterm(至少 Debian 中的版本)会崩溃。尽管手册页中特别提到了这是一种允许的格式。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
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;
}
关于C: 设置伪终端并使用 xterm 打开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22200398/