Рассмотрим следующий код с помощью Google Test.Обратите внимание, что я вообще не добавил никаких тестов.
// File main.cpp
#include <gtest/gtest.h>
using ::testing::InitGoogleTest;
int main( int argc, char* argv[] )
{
InitGoogleTest( &argc, argv );
std::cerr << "INITIAL ERRNO " << errno << std::endl;
int result = RUN_ALL_TESTS();
std::cerr << "FINAL ERRNO " << errno << std::endl;
return result;
}
Я могу скомпилировать это с:
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 |& 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
из test
до stdin
из less
.Есть ли что-то очевидное, что я здесь упускаю?
Примечание: я пишу на C ++ 11, но мне иногда нужно использовать пустой интерфейс C для вещей, которые (в C ++ 17 и более поздних версиях)быть обработан std::filesystem
, как я заметил, что errno
устанавливается.Я слышал, что установка errno
на ноль перед вызовом функций, которые могут установить его, некоторыми людьми рекомендуется для предотвращения подобных проблем, и я могу применить эту практику (в зависимости от комментариев, которые я получаю в ответ), но я бы хотелвсе еще хотел бы понять, что здесь происходит.