przekieruj stdout / stderr do pliku w unix c ++ - ponownie

Co chcę robić

przekieruj stdout i stderr do jednego lub więcej plików z wnętrza c ++

Dlaczego tego potrzebuję

Używam zewnętrznej, prekompilowanej biblioteki innej firmy, która generuje śmieszną ilość danych wyjściowych, którą chciałbym przekierować do pliku dziennika, aby utrzymać konsolę w czystości.

Warunki

Kompatybilność nie jest problemem, kod działa tylko na systemach Unix. Przekierowanie powinno nie tylko wpływać na drukowanie w stylu c ++ (std :: cout << "hello world" << std :: endl), ale także drukowanie w stylu c (printf ("hello world n")).

Co próbowałem do tej pory

Przeglądam stackoverflow przez pół dnia, czytając wiele odpowiedzi dla osób mających podobne problemy. Dzięki tym odpowiedziom udało mi się zebrać następujący fragment kodu:

#include <stdio.h>
#include <iostream>
#include <fcntl.h>
#include "unistd.h"

const int stdoutfd(dup(fileno(stdout)));

int redirect_stdout(const char* fname){
  fflush(stdout);
  int newstdout = open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP |     S_IROTH);
  dup2(newstdout, fileno(stdout));
  close(newstdout);
}

int restore_stdout(){
  fflush(stdout);
  dup2(stdoutfd, fileno(stdout));
  close(stdoutfd);
  return stdoutfd;
}

int main(){
  redirect_stdout("/dev/null");
  std::cout << "invisible 1" << std::endl;
  restore_stdout();
  std::cout << "visible 1" << std::endl;
  redirect_stdout("/dev/null");
  std::cout << "invisible 2" << std::endl;
  restore_stdout();
  std::cout << "visible 2" << std::endl;
  return 0;
}

Co chciałbym zobaczyć:

visible 1
visible 2

Co tak naprawdę widzę

visible 1

Oznacza to, że podczas korzystania z tego mechanizmu po raz pierwszy działa - ale jeśli zostanie ponownie użyty, przywrócenie danych wyjściowych nie będzie działać. Czy ktoś może mi powiedzieć, co muszę zmienić, aby mechanizm działał nieskończenie często?

questionAnswers(5)

yourAnswerToTheQuestion