вторник, 13 января 2009 г.

popen++

Дабы не терять практики в C++ решил опубликовать одну свою старую библиотеку: popen++, которая позволяет создавать дочерние процессы и работать с их потоками (ввода, вывода и ошибок), как со стандартными потоками C++. Например так:
process::popen child = process::popen2("python");

child.stdin() << "print 'TEST_STRING'" << std::flush;
child.close_stdin();

std::string test_string;
child.stdout() >> test_string;
Работает как в Linux (по-хорошему, в POSIX, кажестя один раз проверял для FreeBSD, но уже не помню), так и в Windows (собственно, из-за неё и стал делать эту библиотеку, для Linux в тот момент вполне устраивала PStreams)

Сделано в основном под влиянием соответствующих средств стандартной библиотеки Python. Кроме того, создаваемый объект popen можно использовать в качестве фильтра для boost.iostreams. Также, очень полезной для меня оказалась функция:
void transfer(popen& proc, std::istream& in, std::ostream& out);
Которая позволяет прогнать данные из одного потока в другой через дочерний процесс. Тонкость в том, что некоторые программы (например, Ghostscript) начинают вывод ещё до того, как будет полностью закончен ввод и наивная попытка сначала закачать в такую программу все данные, и только потом попытаться получить вывод может (в случае большого объёма данных) нарваться на ограничение размеров системного буфера и привести к зависанию программы. Правда, в данный момент это корретно реализовано только для Linux (потребности в данной фунции в Windows у меня не возникало, хотя там есть теже проблемы).

Библиотека зависит от boost, какая минимальная версия подходит точно не скажу, но поскольку активно используются возможности boost.iostreams, то точно не ниже 1.33.0.

Для сборки сейчас используется SCons. Написать нормальный "конфигуратор" мне лень, поэтому при желании изменить опции (совершенно необходимо для Windows, где требуется указать путь к boost) необходимо править SConstruct. Я собираю так:
cd popen++
scons
./test+popen++
scons install