如何使一个子进程使用另一个终端输入和输出?

如何使一个子进程使用另一个终端输入和输出?

问题描述:

我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

看看这个链接,看看是否可以帮助你一起... http://stackoverflow.com/questions/15880196/keyboard-device-in-unix – Les

+0

你想让你的子进程打开它自己的“侏儒末端”? – Les

+0

是的,这是真的 – mohammed

标准输入是文件描述符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... 
+0

这样做会阻止父母访问终端的标准输入是不是? – mohammed

+0

不应该,看看http://linux.die.net/man/2/fork – Les

+0

你的答案似乎很好,但我无法理解你正在尝试做什么。 int open(const char * pathname,int flags);什么/ dev/input/tty1与终端有什么关系tty1对不起,我有点新手 – mohammed

当我明白你的问题,你想叉子过程,它与它的所有互动用户通过虚拟终端,即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并自己尝试一下。

+0

感谢您的回答, – mohammed

+0

你能推荐任何书籍或教程,从头开始涵盖这个我需要有人谈论零和我不能理解这些质量保证或者如果你可以提供一个代码示例谢谢。 – mohammed