Перенаправление стандартного вывода при использовании Google Test приводит к установке errno

#c #pipe #stdout #googletest

#c #канал #стандартный вывод #googletest

Вопрос:

Рассмотрим следующий код с использованием Google Test. Обратите внимание, что я вообще не добавлял никаких тестов.

 // File main.cpp

#include <gtest/gtest.h>

using ::testing::InitGoogleTest;

int main( int argc, char* argv[] )
{
    InitGoogleTest( amp;argc, argv );
    std::cerr << "INITIAL ERRNO " << errno << std::endl;
    int result = RUN_ALL_TESTS();
    std::cerr << "FINAL ERRNO " << errno << std::endl;
    return resu<
}
  

Я могу скомпилировать это с:

 g   main.cpp -o test -I/path/to/googletest/1.8.0/include/ -lgtest -L/path/to/googletest/1.8.0/lib/
  

(Я использую g версию 6.1.0 и googletest версию 1.8.0.)

Выполнение test дает мне

 % ./test
INITIAL ERRNO 0
[==========] Running 0 tests from 0 test cases.
[==========] 0 tests from 0 test cases ran. (0 ms total)
[  PASSED  ] 0 tests.
FINAL ERRNO 0
  

Однако передача результатов этого выполнения в less (или передача в view - или перенаправление в файл) дает

 % ./test |amp; less
INITIAL ERRNO 0
[==========] Running 0 tests from 0 test cases.
[==========] 0 tests from 0 test cases ran. (0 ms total)
[  PASSED  ] 0 tests.
FINAL ERRNO 22
  

(Похоже, что критическое перенаправление здесь stdout . Перенаправление stderr само по себе не вызывает проблемы.)

В моей системе 22 соответствует EINVAL .

Что здесь происходит? Я понимаю, что gtest поглощает stdout из основного выполнения, но он также записывает в stdout , поэтому должен быть открытый канал от stdout of test до stdin of less . Есть ли что-то очевидное, чего мне здесь не хватает?

Примечание: Я пишу на C 11, но иногда мне нужно использовать простой интерфейс C для вещей, которые (в C 17 и более поздних версиях) будут обрабатываться std::filesystem , и именно так я заметил, что errno устанавливается. Я слышал, что некоторые люди рекомендуют устанавливать значение errno равным нулю перед вызовом функций, которые могут его устанавливать, для предотвращения подобных проблем, и я могу применить эту практику (в зависимости от комментариев, которые я получаю в ответ), но я все равно хотел бы понять, что здесь происходит.

Комментарии:

1. Я предполагаю, что Google Test выполняет какую-то операцию над стандартным выводом, которая разрешена, когда стандартный вывод переходит к интерактивному терминалу, но не когда стандартный вывод переходит к файлу или каналу. Попробуйте запустить обе команды в strace и сравнить результаты. Но почему вас это волнует?

2. @rveerd Я просто предпочитаю потратить время на понимание вещей, которые меня удивляют. Я не использовал strace раньше, поэтому попробую это. Спасибо!