我用谷歌搜索了很多,但没有找到任何真正满足我需求的解决方案。
我需要分叉子进程来使用另一个终端的 stdin 和 stdout,而不是在此处调用它的终端,这是我想要做的示例
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int main()
{
pid_t pid;
printf("process parent pid is %d\n",getpid());
pid =fork();
printf("process child pid is %d\n",pid);
if(pid==0)
{
//int exit_status = system("gnome-terminal");
char a[20];
while(1)
{
scanf(" %s",a);
printf("child %s \n",a);
}
}
while(1)
{
char b[20];
scanf(" %s",b);
printf("parent %s \n",b);
}
}
例如,我需要孩子通过另一个终端与用户交互。
据我了解您的问题,您希望分叉一个子进程,该进程通过虚拟终端(即 gnome-terminal)与用户进行所有交互。 然后,首先,阅读这篇文章,了解终端和 shell 之间的区别。然后阅读关于 Unix 伪终端的这篇文章。然后阅读这篇关于 /dev/pts 文件系统的文章。这将为您提供我的回答的背景。
这是创建连接到不同终端(虚拟终端)的子进程的一种方法。我承认,我已经很长时间没有这样做了,而且是使用物理 TTY,而不是伪终端。但背景信息应该可以帮助您克服可能遇到的任何困难。总体方法是分叉两个子进程。一种用于虚拟终端,一种用于工作进程。然后,您将执行虚拟终端进程,使其在 shell 退出时不会关闭。您实际上甚至不希望它启动 shell 或任何与此相关的程序,因为您将提供与其交互的正在运行的进程。对于 gnome-terminal,要让它在进程退出后继续停留并不容易。您应该
阅读本文以获取有关如何保留它的建议。另一种选择是使用“xterm”,它具有“--hold”选项,该选项似乎适合该目的。 “xterm”还有“-S”选项,听起来与您所需要的完全一样。要使用“-S”选项,您需要阅读PTS
由于 XTERM 具有您需要的选项,因此我将描述基于 XTERM 而不是 gnome-terminal 的方法。在您的子程序中,您需要打开 /dev/ptmx 来获取主伪终端文件描述符。然后,您可以在 FD 上调用 ptsname() 来获取 PTS 的名称。您需要该名称来通知 XTERM 要使用哪个从属 PTS。您必须通过在主 FD 上调用 grantpt() 和unlockpt() 来授予访问权限并解锁 FD。接下来,分叉另一个进程并使用 -S 选项执行 exec() XTERM,该选项采用“-S/dev/pts/123/42”或等效的“-S123/42”形式的 PTS 名称和文件描述符编号。在这种情况下,我认为您不需要“--hold”,但如果事实证明您需要,请添加它。 (有关使用 -S 的更多信息,请参阅 XTERM 手册页)
这会将终端建立为子进程的主伪终端文件描述符上的用户 I/O 设备。因此,接下来您将把文件描述符 dup() 到 fd 0 和 fd 1 上(如果您希望 stderr 到达那里,则还可以将文件描述符复制到 fd 2 上)。
很抱歉这太笼统了。该方法应该可行,但您可能需要根据您的特定 Linux/Unix 风格进行调整。请让我知道你是怎么做的,如果有机会,我会安装一个 Linux 并亲自尝试一下。
您需要获得权限才能打开设备。
例如,假设您感兴趣的输入设备是 /dev/input/tty1...
if(childpid == 0)
{
int fd = open("/dev/input/tty1", open_args);
if(fd >= 0)
{
/* Close stdin, duplicate the fd just opened to stdin */
dup2(0, fd);
// etc...