2016-09-28 12 views
0

私は子プロセスを生成するアプリケーションを持っています。その子プロセスは、stdoutに印刷することによって、何をしているのかに関する情報を出力します。親プロセスは同じことをする(すなわち、標準出力に出力する)。子プロセスコンソール出力を先頭に追加

子プロセスでは、いくつかのテキストを前置してstdoutに書き込むことができますが、多くのソースファイルにまたがって印刷するすべての単一の場所に追加する必要があります。

私は、親プロセスが子プロセスからfork/execの出力をprependすることが賢明かもしれないと考えました。親プロセスとインラインで出力するのが有益なので、出力をリダイレクトしたくありません。これはどうすればいいですか?親でfork/execを使用しています。

出力を読み、手動で各行を追加する必要がありますか、より簡単な方法がありますか?


更新:Barmarへ

感謝。ここで私はそれをやっている方法です。私はまた、パイプから行末まで親プロセスのバイト単位で読むことができました。しかし私は、シングルスレッド化されたlua + Cアプリケーションの複雑さのためにこのアプローチを使用しないことを選択しました。

// Crude example of output filtering using sed to 
// prepend child process output text 

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <libgen.h> 
#include <string.h> 


pid_t spawn(int fd[2], const char* path) 
{ 
    printf("Create child\n"); 
    pid_t pid = fork(); 
    switch(pid){ 
    case -1: 
     printf("Create process failed"); 
     return -1; 
    case 0: 
     dup2(fd[1], STDOUT_FILENO); 
     close(fd[0]); 
     close(fd[1]); 
     execl(path, path, NULL); 
     return 0; 
    default: 
     return pid; 
    } 
} 

pid_t spawnOutputFilter(int fd[2]) 
{ 
    printf("Create sed\n"); 
    pid_t pid = fork(); 
    switch(pid){ 
    case -1: 
     printf("Create sed failed"); 
     return -1; 
    case 0: 
     dup2(fd[0], STDIN_FILENO); 
     close(fd[0]); 
     close(fd[1]); 
     execlp("sed", "sed", "s/^/Engine: /", (char *)NULL); 
     return -1; 
    default: 
     return pid; 
    } 
} 


int main(int argc, char* argv[]) 
{ 
    if (argc > 1){ 
    int options; 
    int fd[2]; 
    pipe(fd); 
    pid_t pid = spawn(fd, argv[1]); 
    pid_t sed_pid = spawnOutputFilter(fd); 

    close(fd[0]); 
    close(fd[1]); 
    waitpid(pid, NULL, 0); 
    waitpid(sed_pid, NULL, 0); 
    } 

    return 0; 
} 
+1

コードの構造によっては、次のようなことができます: '#define printf printf(" prepend "); printf' – Riley

答えて

2

あなたは

execlp("sed", "sed", "s/^/PREFIX: /", (char *)NULL); 

がパイプと、このプロセスの標準入力に最初の子供のstdoutを接続して行う第2子プロセスを作成することができます。

+1

ニット: '' s/^/PREFIX:/ "' else expect '' unterminated ''コマンド ' –

+0

うまくいくと思われます。 – Matt

0

あなたは私が考えることができる#define printf(a) printf("your text:" a).

他の代替が

dupあなたはあなたの子プロセスで同じログファイルを開き、dupあなたstdout新しいファイルディスクリプタに使用されて定義されていませんでした。

+0

複数の' printf'パラメータではうまくいかないと思います... –

+0

おそらく。技術的にはC&Luaが混在しているので、出力はいくつかの場所から来ています。 #defineはluaでは動作しませんが、私が想定している別のルーチンで印刷するためのすべての呼び出しを置き換えることができます。それはまだ面倒です。 – Matt

+0

退屈?どうして?唯一の選択肢は、 'write'システムコールをフックし、pidをチェックして、別のプロセスでそれを別々に扱うことです。 *これは面倒です。 –

2

私は、親プロセスに子プロセスからのプリペンド出力を持たせるほうがいいかもしれないと考えました。

「スマート」と判断する方法によって決まります。子供がその出力に所望のテキストを付加するようにするのは、2より簡単なです。

出力をリダイレクトしたくないのは、親プロセスとのインライン出力が有益だからです。これを行う最善の方法は何ですか?

オープンされたファイルを共有する2つのプロセスは、それらのプロセス間の関係の性質にかかわらず、どちらも独立してアクセスします。したがって、あなたの子供が親のstdoutを継承している場合、親はその子が出力を送信していることに気づくことさえもなく、その出力を変更することはできません。

親がこれを処理するようにするには、親を通して子の出力を渡す必要があります。パイプを作成し、子のstdoutをそのパイプの書き込み側に関連付けることで、これを行うことができます。次に、親は読み取り終了を監視し、適切に修正された出力を自身のstdoutに転送する必要があります。親はおそらくその目的のために別のスレッドを作成したいと思うでしょう。

さらに、子が、行単位ではなくグループとしてプレフィックスを付ける複数行出力を生成する場合は、メッセージ境界を画定するために何らかのプロトコルを構築して使用する必要があります。親のモデレーションの考え方全体をかなり無意味にする。

関連する問題