如何使一个子进程使用另一个终端输入和输出?
我GOOGLE了很多,但没有找到任何真正的解决方案来满足我的需求。如何使一个子进程使用另一个终端输入和输出?
我需要的分叉子进程使用标准输入和标准输出另一个终端,而不是把它叫做这里是我想要做的
#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);
}
}
我需要孩子的例子之一的例如通过另一个终端与用户交互。
标准输入是文件描述符0连接到另一个文件或流(或设备),你的孩子的过程必须先关闭文件描述符0,然后打开另一个文件(设备)。打开将返回fd 0(如果成功),因为它现在是第一个可用的。您可以使用dup()以原子方式执行此操作。
您需要权限才能打开设备。
例如,假设感兴趣的是/ dev /输入/ 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...
当我明白你的问题,你想叉子过程,它与它的所有互动用户通过虚拟终端,即gnome-terminal。 然后,首先,阅读this article关于终端和壳之间的区别。然后阅读关于Unix伪终端的this article。然后read this one关于/ dev/pts文件系统。这会给你我的答案的背景。
下面是创建一个连接到不同的终端,虚拟终端子进程的一种方式。我承认,我很久没有这样做了,然后是一个实体TTY,而不是一个伪终端。但背景信息应该可以帮助你克服任何可能遇到的麻烦。
整体方法是分叉两个子进程。一个用于虚拟终端,另一个用于工作进程。然后,您将执行虚拟终端进程,使其在shell退出时不会关闭。你甚至不希望它为这个问题启动一个shell或任何程序,因为你将提供正在运行的进程并与之交互。使用gnome-terminal,在流程退出后不容易告诉它挂起。你应该read this得到如何保持它的建议。另一种方法是使用“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名称和文件描述符编号。在这种情况下,我认为你不需要“ - ”,但如果事实证明你这么做,就加上它。 (请参阅Xterm手册页的详细信息,使用-S)
这确立了以终端为用户I/O设备上的子进程的主pseuo端文件描述符。因此,接下来,您将文件描述符重复()到fd 0和fd 1(如果您希望stderr去那里,则fd 2)。
对不起,这是如此普遍。这种方法应该可行,但你可能需要为你的特定的Linux/Unix风格调整它。请让我知道你是怎么做的,如果我有机会,我会得到一个Linux并自己尝试一下。
看看这个链接,看看是否可以帮助你一起... http://stackoverflow.com/questions/15880196/keyboard-device-in-unix – Les
你想让你的子进程打开它自己的“侏儒末端”? – Les
是的,这是真的 – mohammed