5
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int
main( int argc, char **argv)
{
    int pfds[ 2], i;
    size_t pbytrd;
    pid_t childpid;
    char buffer[ 200];

    pipe( pfds);
    if( ( childpid = fork() ) == -1)
    {
            perror( "fork error: ");
            exit( 1);
    }
    else if( childpid == 0)
    {
            close( pfds[ 0]);
            dup2( pfds[1], 1);
            close( pfds[ 1]);
            for( i = 0; i < 10; i++)
               printf("Hello...");
            execlp( "xterm","xterm","-e","./sample_a", (char *) 0);
            exit( 0);
}
else
{

        close( pfds[ 1]);
        for( ; ; )
        {
            if( ( pbytrd = read( pfds[ 0], buffer, sizeof( buffer) ) ) == -1)
            {
                perror(" read error: ");
                exit( 1);
            }
            else if( pbytrd == 0)
            {

                write( fileno( stdout), "Cannot read from pipe...\n", strlen( "Cannot read from pipe...\n") );
                exit( 0);
            }
            else
            {
                write( fileno( stdout), "MESSAGE: ", strlen( "MESSAGE: ") );
                write( fileno( stdout), buffer, pbytrd);
            }
        }       
}   
return( 0);

}

My sample_a.c code is below:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int
main( int argc, char **argv)
{
        int i;
        for( i= 0; i< 10; i++)
        write( fileno( stdout), "Hello...", strlen( "Hello...") );
    return( 0);
 }

In the above code, what I really want to do is: 1) Redirect output from the child process to pipe and have parent read from the pipe and print it out to stdout.

I am able to redirect child process output( "printf") from stdout to the pipe but I am not able to redirect execlp's child process, xterm, output to the pipe.

Can anybody help me this?

4

4 回答 4

4

xterm是一个终端仿真器。它执行你提供的程序sample_a

您的程序正在做的是将xterm输出连接到管道,并尝试读取它。但xterm它是一个 GUI 程序,它通常不会将数据写入其输出。也许还不清楚您到底要达到什么目标。

如果您删除该xterm部分,它应该可以按预期工作,即父进程将看到sample_a写入输出的内容。

        execlp("./sample_a", "./sample_a", (char *) 0);
于 2011-02-12T23:48:21.007 回答
1

我遇到了类似的情况。我的目标是从在 xterm 中运行的子进程发送一些信息。如前所述,我无法使用 dup2。一种解决方法是将 fd 作为 xterm args 传递给新的二进制文件。

建议的方法(为简洁起见没有错误检查)是

if (childpid  == 0)
{
    /* child closes read*/
    close(pipeFD[0]);
    char writeFD[10]; // do consider space for '\0'
    /* Extract the write fd and put it in a char buffer 
       make compatible as per execlp args */
    sprintf(writeFD, "%d", pipeFD[1]); 
    /* just pass the writeFD as an arg */
    execlp("xterm", "xterm", "-e", "./binary", writeFD, (char *) 0))

}
else
{
    /* parent closes write */
    close(pipeFD[1]);
    if((bytesRead = read(pipeFD[0], buf, SIZE)) != -1)
    {
        printf("Recieved %s\n", buf);
        close(pipeFD[0]);
    }
 }

在 xterm 中运行的子进程上,提取 fd

main(int argc, char** argv) {
   int fd = atoi(argv[1]);
   write(fd, buf,sizeof(buf));
}     

我不知道为什么 dup2dose'nt 与 xterm 一起工作,但这种解决方法解决了这个要求。

于 2011-09-20T01:52:16.663 回答
1

xterm 没有输出,因此无法将其重定向到任何地方。xterm 运行一个子进程并将子进程的输出重定向到它自己,因此如果您想将子进程的输出重定向到 xterm 以外的其他位置,您需要自己在子进程中执行此操作,在 xterm 启动它之后。最简单的方法可能是让 xterm 启动一个 shell 并使用 shell 重定向。要为孩子重定向 stderr,您可以使用以下内容:

execlp("xterm", "xterm", "-e", "/bin/sh", "-c", "./sample_a 2>somewhere", 0);

somewhere适当的东西代替。假设你想在你的原始程序中捕获它,你可能想用 tempnam(3) 和 mkfifo(3) 创建一个临时 fifo 并打开它以便在你的父程序中读取。你需要在 fork 之前创建它并在 fork 之后打开它,因为 open 会阻塞,直到 shell 运行并打开写入端。打开完成后,您可以删除该 fifo,并从现在未命名的 fifo 中读取。

于 2011-02-13T02:10:03.417 回答
1

一旦你创建了一个 xterm 窗口,pipeFD 数组就存储了 in 和 out 两个文件描述。子进程不知道在哪里写。所以你可以使用 dup2:

dup2(pipeFD[1],100);
close(pipeFD[1]);

它将旧的写入端口映射到新端口(其他数字也可以)。在 xterm 中,您可以通过

write(100,"something you wanna to write").
于 2014-10-02T03:52:51.017 回答