перенаправить stdout / stderr в файл под Unix C ++ - снова

Что я хочу сделать

перенаправить stdout и stderr на один или несколько файлов изнутри c ++

Зачем мне это нужно

Я использую внешнюю, предварительно скомпилированную стороннюю библиотеку, которая производит смехотворное количество выходных данных, которые я хотел бы перенаправить в файл журнала, чтобы сохранить консоль в чистоте.

условия

Совместимость не является проблемой, код будет работать только на системах Unix. Перенаправление должно влиять не только на печать в стиле c ++ (std :: cout << "hello world" << std :: endl), но и на печать в стиле c (printf ("hello world \ n")).

Что я пробовал до сих пор

Я полдня просматривал stackoverflow, читая несколько ответов для людей, имеющих схожие проблемы. С помощью этих ответов я смог собрать следующий фрагмент кода:

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

Что бы я ожидал увидеть:

visible 1
visible 2

Что я на самом деле вижу

visible 1

То есть при первом использовании этого механизма он работает, но при повторном использовании восстановление выходных данных работать не будет. Может кто-нибудь указать мне, что мне нужно изменить, чтобы механизм работал бесконечно часто?

Ответы на вопрос(5)

Ваш ответ на вопрос