【问题标题】:C: setup pseudoterminal and open with xtermC: 设置伪终端并使用 xterm 打开
【发布时间】:2014-03-05 14:21:14
【问题描述】:

下面的简化代码由后台线程执行。线程一直运行,直到他被告知退出(通过用户输入)。

在下面的代码中,我删除了一些错误检查以提高可读性。即使有错误检查,代码也能正常工作,并且创建和/或打开主从。

...
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 进程是否是上述程序的子进程,是否继承了文件描述符 3?
  • 不,不是(还没有)。出于测试目的,我想从第二个 shell 手动运行它。
  • 好吧,如果 xterm 进程实际上没有具有文件描述符 3,则指定 3 作为要使用的 dfile 描述符对您没有好处。

标签: c unix xterm


【解决方案1】:

xterm 进程需要以某种方式访问​​文件描述符。此功能的预期用途可能是将 xterm 作为创建 pty 的子进程启动。不过,还有其他方法。你可以使用 SCM_RIGHTS 文件描述符传递(相当复杂)或者,如果你有一个 Linux 风格的 /proc 文件系统试试这个:

xterm -S4/3 3<>/proc/$PID_OF_YOUR_OTHER_PROGRAM/fd/3

' 您之前可能见过 shell 重定向运算符:&lt; 用于标准输入,&gt; 用于标准输出,2&gt; 用于标准错误(文件描述符 2)。也许您还看到其他文件描述符被打开以进行输入或输出,例如3&lt;inputfile 4&gt;outputfile。好吧,这里的3&lt;&gt; 运算符是另一个运算符。它以读/写模式打开文件描述符 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;
}

【讨论】:

  • 非常感谢。那么有没有办法从终端手动完成呢?
猜你喜欢
  • 2011-10-10
  • 1970-01-01
  • 1970-01-01
  • 2011-10-11
  • 1970-01-01
  • 2023-02-06
  • 2021-05-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多