#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
раньше, поэтому попробую это. Спасибо!