6

stderr を受動的にリッスンし、コールバックに送信するための文字列として取得するにはどうすればよいですか? stderr を読んでいるという投稿を見たことがありますが、積極的に読むのではなく、聞きたいです。

背景: 詳細情報を stderr に出力するサードパーティ ライブラリ (libcurl) を使用するクロスプラットフォームの作品があります。このクロスプラットフォーム部分は、複数の非クロスプラットフォーム アプリケーションで使用されます。

これらの情報をログに記録したいと思います。これは、FILE* を libcurl に提供することで実行できます。しかし、それを行う代わりに、stderr の出力を string としてキャプチャ (受動的にリッスン) し、コールバックを介して呼び出し元のメイン アプリケーションに送り返すことができるかどうかを確認したいと考えています。これには次の利点があります。 1. メイン アプリは、必要なログ ツールを使用して単一のログを保持できます。2. この作品をクロスプラットフォームに保ちます。

4

1 に答える 1

2

これを 1 つのプロセスで実行するのは少し難しいですが、おそらく実行できます。

  • 1: freopen() を使用すると、stderr を名前付きファイルにリダイレクトできます。別のハンドルで読み取るために、そのファイルを同時に開くことができます。また、stderr で setvbuf() を呼び出して stderr への出力のバッファリングをオフにし、2 番目のハンドルからすぐに読み取れるようにする必要がある場合もあります。ファイルに書き込まれているので、都合のよいときにいつでも読み取ることができます。ファイルが変更されたときに通知を受け取りたい場合は、UNIX 関数の「select」が必要です。(fileno() も参照)。

  • 2: stderr をパイプの書き込み側として設定するのは、さらにトリッキーです。dup3() を使用して実行できるはずですが、これは正確にはクロスプラットフォームではありません (非 unixy OS に対して)。また、書き込みが多すぎる場合にライターがブロックされるのを防ぐために、2 番目のスレッドがパイプから読み取る必要があります。

お気に入り:

FILE *stream = freopen("stderr.out", "w", stderr); // Added missing pointer
setvbuf(stream, 0, _IONBF, 0); // No Buffering
FILE *input = fopen("stderr.out", "r");
fprintf(stderr, "Output to stderr dude\n");
//fflush(stderr); // You can explicitly flush instead of setting no buffering.
char buffer[1024];
while (fgets(buffer, 512, input))
{
    printf(">>>%s\n", buffer);
}
于 2012-11-25T05:45:09.590 に答える