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)。 也许您还看到其他文件描述符正在输入或输出,例如3outputfile 。 那么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; }