以下简化的代码段由后台的线程执行。该线程一直运行,直到他被告知退出(通过用户输入)。
在下面的代码中,我删除了一些错误检查以获得更好的可读性。即使有错误检查,代码也能很好地工作,并且创建和/或打开主设备和从设备。
...
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
。两者都不起作用。
答案 0 :(得分:1)
xterm进程需要以某种方式访问文件描述符。此功能的预期用途可能是将xterm作为创建pty的子进程启动。不过还有其他方法。你可以使用SCM_RIGHTS文件描述符传递(非常复杂),或者,如果你有一个Linux风格的 /proc
文件系统,试试这个:
xterm -S4/3 3<>/proc/$PID_OF_YOUR_OTHER_PROGRAM/fd/3
”
您可能以前见过shell重定向运算符:stdin为<
,stdout为>
,stderr为2>
(文件描述符2)。也许您还看到其他文件描述符正在输入或输出像3<inputfile 4>outputfile
这样的东西。那么3<>
运算符就是另一个运算符。它以读/写模式打开文件描述符3。 /proc/PID/fd/NUM
是访问另一个进程打开的文件的便捷方式。
我不知道其余的问题。我之前没有尝试过使用这种xterm模式。
好的,/proc
的诀窍是个坏主意。这相当于/dev/ptmx
的新开放,创造了一个新的无关的pty。
你将不得不让xterm成为你的pty创建程序的孩子。
这是我用来探索该功能的测试程序。它很草率,但它揭示了一些有趣的事情。一个有趣的事情是xterm在成功初始化后将其窗口ID写入pty主服务器。这是你需要处理的事情。它在实际用户输入开始之前显示为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;
}