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);

}

私の sample_a.c コードは次のとおりです。

#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);
 }

上記のコードで、私が実際にやりたいことは次のとおりです。1) 子プロセスからの出力をパイプにリダイレクトし、親がパイプから読み取って stdout に出力するようにします。

子プロセスの出力 (「printf」) を stdout からパイプにリダイレクトできますが、execlp の子プロセス xterm の出力をパイプにリダイレクトできません。

誰でもこれを手伝ってもらえますか?

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には出力がないため、どこにでもリダイレクトする方法はありません。xtermは子を実行し、子の出力をそれ自体にリダイレクトします。したがって、子の出力をxterm以外の場所にリダイレクトする場合は、xtermが起動した後、子で自分で行う必要があります。これを行う最も簡単な方法は、おそらくxtermにシェルを開始させ、シェルリダイレクトを使用することです。子のstderrだけをリダイレクトするには、次のようなものを使用します。

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

somewhere適切なものと交換してください。元のプログラムでそれをキャプチャしたい場合は、tempnam(3)とmkfifo(3)を使用して一時的なFIFOを作成し、それを開いて親で読み取ることができます。シェルが実行されて書き込み終了が開かれるまでopenがブロックされるため、フォークする前に作成し、フォーク後に開く必要があります。オープンが完了したら、FIFOを削除して、名前のないFIFOから読み取ることができます。

于 2011-02-13T02:10:03.417 に答える
1

xterm ウィンドウを作成すると、pipeFD 配列には in と out の 2 つのファイル記述が格納されます。子プロセスは書き込み先を知りません。したがって、dup2を使用できます:

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

古い書き込みポートを新しいポートにマップします (他の番号も機能します)。そしてxtermでは、パイプに書き込むことができます

write(100,"something you wanna to write").
于 2014-10-02T03:52:51.017 に答える
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));
}     

dup2 が xterm で動作しない理由はわかりませんが、この回避策で要件が解決されます。

于 2011-09-20T01:52:16.663 に答える