Я реализую конвейер на смоделированной файловой системе в С++ (в основном с C). Он должен запускать команды в оболочке хоста, но выполнять сам трубопровод в имитируемой файловой системе.
Я мог бы добиться этого с помощью системных вызовов pipe(), fork() и system(), но я бы предпочел использовать popen() (который обрабатывает создание канала, форматирование процесса и передачу команды оболочка). Это может быть невозможно, потому что (я думаю) мне нужно иметь возможность писать из родительского процесса в трубе, читать на конце дочернего процесса, записывать выходные данные из дочернего элемента и, наконец, читать этот вывод из родителя. Страница руководства для popen() в моей системе говорит, что возможна двунаправленная трубка, но мой код нужно запускать в системе со старой версией, поддерживающей только однонаправленные каналы.
С помощью отдельных вызовов выше я могу открыть/закрыть трубки, чтобы достичь этого. Возможно ли это с помощью popen()?
Для тривиального примера для запуска ls -l | grep .txt | grep cmds мне нужно:
- Откройте канал и процесс для запуска
ls -lна хосте; прочитайте его вывод назад - Произведите вывод
ls -lна мой симулятор - Откройте трубу и процесс для запуска
grep .txtна хосте на выходном каналеls -l - Произведите вывод этой обратной связи на симулятор (застрял здесь)
- Откройте трубку и процесс для запуска
grep cmdsна хосте на выходном каналеgrep .txt - Произведите вывод этой задней части на симулятор и распечатайте его
man popen
Из Mac OS X:
Функция
popen()"открывает" a процесса путем создания двунаправленного трубы, разветвления и вызова оболочки. Любые потоки, открытые предыдущимpopen()вызовы в родительском процессе закрыты в новом дочернем процессе. Исторически сложилось, чтоpopen()с однонаправленной трубой; следовательно, существует множество реализацийpopen()разрешить аргумент режима чтение или письмо, а не оба. Потому какpopen()теперь реализуется с использованием двунаправленная труба, аргумент режима может запросить двунаправленный поток данных. Аргумент mode является указателем на нулевая строка, которая должна быть 'r' для чтения, 'w' для записи или "r +" для чтения и записи.