Закройте стандартную строку boost :: process child

Я пытаюсь вызвать процесс со строкой к его стандартному, с Boost-1.64.0.
Текущий код:

  bp::opstream inStream ;
bp::ipstream outStream;
bp::ipstream errStream;

bp::child child(
command, // the command line
bp::shell,
bp::std_out > outStream,
bp::std_err > errStream,
bp::std_in  < inStream);// read the outStream/errStream in threads

child.wait();

Проблема в том, что дочерний исполняемый файл ожидает своего стандартного EOF. Здесь child.wait () висит бесконечно …

Я пытался использовать asio :: buffer, std_in.close (), … Но не повезло.
Единственный хак, который я нашел, это удалить () inStream … И это не совсем надежно.

Как я должен «уведомить» дочерний процесс и закрыть его стандартный ввод с новой библиотекой boost :: process?

Спасибо !

2

Решение

Я пытался использовать asio :: buffer, std_in.close()

Это работает. Конечно, это работает, только если вы передаете его в функцию запуска (конструктор bp :: child, bp :: system и т. Д.).

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

boost::asio::async_write(input, bp::buffer(_stdin_data), [&input](auto ec, auto bytes_written){
if (ec) {
logger.log(LOG_WARNING) << "Standard input rejected: " << ec.message() << " after " << bytes_written << " bytes written";
}
may_fail([&] { input.close(); });
});

куда input является

bp::async_pipe input(ios);

Кроме того, проверьте, что процесс на самом деле не застрял при отправке вывода! Если вы не сможете использовать вывод, он будет буферизироваться и ждать, если буфер заполнен.

2

Другие решения

Закрытие трубы по телефону inStream.close(); когда вы закончите писать к нему. Вы также можете закрыть его при запуске с bp::std_in.close().

Решение asio, конечно, также работает и позволяет избежать опасности тупиков.

1