2012-11-23 8 views
5

Come ascoltare passivamente lo stderr e ottenerlo come stringa per l'invio alla richiamata? Ho visto post su read stderr ma voglio ascoltarlo piuttosto che leggerlo attivamente.Come ascoltare lo stderr in C/C++ per l'invio alla richiamata?

Sfondo: Ho un pezzo multipiattaforma che utilizza la libreria di terze parti (libcurl) che genererà informazioni dettagliate in stderr. Questo pezzo multipiattaforma deve essere utilizzato da più di 1 applicazioni non multipiattaforma.

Vorrei registrare queste informazioni, che posso fare fornendo FILE * a libcurl. Ma invece di farlo, voglio vedere se riesco a catturare (ascoltare passivamente) l'output in stderr come stringa e inviarlo all'applicazione principale chiamante tramite callback. Questo ha il vantaggio di 1. l'app principale può mantenere un singolo log usando qualunque strumento di registrazione che vuole. 2. manterrà questo pezzo multipiattaforma.

+0

vedere questo http://stackoverflow.com/questions/5095839/redirect-from-stderr-to-another-file-descriptor – kellogs

+0

Così è C o C++ poi? – netcoder

+0

C++. Ma non uso molto std (non ero sicuro che fosse abbastanza multipiattaforma). –

risposta

2

Fare questo in un unico processo è un po 'complicato, ma probabilmente lo puoi fare.

  • 1: Utilizzo freopen() è possibile reindirizzare la tua stderr in un file denominato. È possibile aprire contemporaneamente quel file per la lettura su un altro handle. Potrebbe anche essere necessario chiamare setvbuf() su stderr per disattivare il buffering sull'output su stderr in modo da poterlo leggere subito dopo il secondo handle. Poiché è stato scritto su un file, puoi leggerlo in qualsiasi momento, quando è conveniente. La funzione unix "select" è ciò di cui hai bisogno se vuoi essere avvisato quando il file cambia. (vedi anche fileno()).

  • 2: Più difficile sarebbe impostare stderr come fine scrittura di una pipe. Dovrebbe essere fattibile usando dup3(), anche se questo non è esattamente multipiattaforma (rispetto ai sistemi operativi non-unixy). Richiederebbe inoltre che un secondo thread sia letto dalla pipe per impedire che lo scrittore venga bloccato se scrive molto.

come:

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