Я реализую конвейер на смоделированной файловой системе в С++ (в основном с 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 +" для чтения и записи.