C:设置伪终端并使用xterm打开

时间:2014-03-05 14:21:14

标签: c unix 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。两者都不起作用。

1 个答案:

答案 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;
}