LINUX.ORG.RU

Запись в stdin и чтение из stdout дочерних процессов

 , , , ,


3

4

Я делаю новую среду программирования, в котором Си используется в качестве бэкенда, попутно сам осваиваю Си. Приходится компилировать в gcc.

Нужно вызвать gcc, записав в его stdin код, а из его stdout получить результат. Подскажите чайнику как это делается.

Ответ на: комментарий от vladimir_vist

popen действует только в одну сторону. Либо писать в stdin дочернего процесса, либо читать из stdout. А надо делать и то, и другое.

metaprog ()

записав в его stdin код, а из его stdout получить результат.

Тебе нужно создать две трубы с помощью pipe(). Потом вызвать fork(), затем в потомке перебросить нужные выводы труб на дескрипторы 0 и 1 с помощью dup2(), затем закрыть ненужные концы труб в потомке (все четыре) и заменить дочерний процесс нужным через execl(). В родителе тоже закрываешь ненужные концы труб (две). Итого в родителе у тебя остаётся два файловых дескриптора. То, что пишешь в один, попадает в stdin потомка, а данные из stdout потомка попадают в другой оставшийся дескриптор.

Закрытие дескрипторов в потомке можно выбросить, если открывать трубу с O_CLOEXEC.

i-rinat ★★★★★ ()
Ответ на: комментарий от Einstok_Fair

Не очень хороший пример. Там процесс к консоли цепляется, поэтому все стандартные дескрипторы привязываются к одному файлу.

i-rinat ★★★★★ ()
Ответ на: комментарий от Einstok_Fair

Metaprog

Хороший вопрос. Хочу программировать мышкой, а не клавиатурой. В графике, а не в тексте. Пока что это позволяет на приличном уровне только пропиетарное LabVIEW. Трудно поверить, что это единственная полностью графическая среда программирования серьезного уровня в 2019 году! Но даже в нем есть куча недостатков (которые невозможно самостоятельно устранить из-за пропиетарности).

Графическое программирование намного проще и понятнее. Если в качестве бэкенда брать Си и манипулировать функциями из сишной стандартной библиотеки, это не будет создавать никаких лишних абстракций, зато серьезно упростит жизнь программистам и особенно людям, имеющим дело с чужим кодом. Код любого уровня и любой сложности, представленный в виде графических блоков, станет открытым не только для узких специалистов, но и вообще любому продвинутому пользователю. Простота программирования и эффективность, не меньшая, чем у Си, убьет C++, Python, Java, Javascript и прочую ерунду с раздутыми и полными багов абстракциями (которые Линус не раз крыл матом).

Я уже делаю некое подобие LabVIEW на самом LabVIEW, назовем его Metaprog. Так же, как в 1991 Линус Торвальдс делал линукс, пользуясь пропиетарным Minix. И так же жаловался на кучу недостатков в Minix, желая устранить их в своей системе.

Я уже рисую простенькие блок-схемы. Добился того, что функции, типы, структуры, юнионы из сишных #include сразу отображаются в виде меню, что серьезно упрощает знакомство со стандартной библиотекой Си. Сейчас нужно научить Metaprog «компилировать» блок-схемы прямо в Си и скармливать этот код gcc, получая бинарники. После чего перенести сам Metaprog на Си, чтоб перестать нуждаться в пропиетарном LabVIEW и выложить результаты в опенсорс. И получить за это донат, хотя желательно уже сейчас (для ускорения работы). Bitcoin:1AYoK2TScSpD5bhf67mv9AxHDJ2RidRvjD

metaprog ()
Ответ на: Metaprog от metaprog

Это всё не ответ на вопрос, почему всё это визуальное нельзя было вкорячить внутрь Gnome Builder

Einstok_Fair ★★☆ ()
Ответ на: комментарий от Einstok_Fair

Потому что там надо было бы сначала писать многое в тексте.

metaprog ()
Ответ на: комментарий от i-rinat

тс'у это может быть не интересно, но все же.

а что делать с буферизацией в stdio? имеет значение, когда нужен построчный выхлоп stdout потомка.

conalex ★★★ ()
Ответ на: комментарий от conalex

когда нужен построчный выхлоп stdout потомка

Без понятия. Буферизация вывода ведь внутри потомка происходит.

Утилита stdbuf эту проблему решает подгрузкой so-шки в дочерний процесс, где та вызывает setvbuf() с нужными параметрами.

i-rinat ★★★★★ ()

посмотри BaCon + GTK SERVER примеры. ну или даже M4basic исходный и шеллдрайвер оттуда.

Нужно вызвать gcc, записав в его stdin код, а из его stdout получить результат. Подскажите чайнику как это делается.

popen или mkpipe, и перекрываешь дескрипторы stdin/stdout по умолчанию.

в принципе из шелла ничего не мешает делать что-то типа gcc - или через HEREDOC.

anonymous ()
Ответ на: Metaprog от metaprog

Re: Metaprog

если разобраться с RED/System и научить генерировать метаданные для RED/System и FFI, а затем взять RED который на RED/System и научиться генерировать его, то можно получить всё то же самое, только расширяемое. потому что потом какой-то AST макрос например написать на RED который будет его расширять, ну и всё такое прочее.

в итоге может получиться зело проще.

или например, какую-то ООП систему простенькую типа cello к С прикрутить.

то есть: тебе нужен не низкоуровневый язык и его конкретный синтаксис, а настраиваемый метаязык, специализированный в конкретные низкоуровневые, и какие-то конкретные возможности по вызову низкоуровневых.

Сейчас нужно научить Metaprog «компилировать» блок-схемы прямо в Си и скармливать этот код gcc, получая бинарники.

например, взять тот же BaCon бейсик на bash, транспилируемый в си. и компилировать в бейсик, который проще. а затем c, gcc, и бинарники.

вот расширять языки типа си в ооп или типа бейсика (интересно, во что?) сложнее. а типа лиспа или ребола или red из низкоуровневого RED/System в высокоуровневый RED и прочие DSL поверх него — проще.

anonymous ()

Нужно вызвать gcc, записав в его stdin код, а из его stdout получить результат.

В общем случае это невозможно, т.к. на каком-то размере данных вызываемый процесс откажется принимать данные пока из него не заберут то, что он уже нагенерил. Получится т.н. deadlock.

Всякие буферы в анонимных и именованных каналах pipe и очередях fifo поначалу скрадывают этот эффект от неопытного unix-разработчика, но дедлок неминуемо проявит себя.

Поэтому результат надо либо скармливать третьему процессу (на баше это prog1 | gcc | prog2), либо накапливать в хранилище произвольного размера (называется «файл»).

legolegs ★★★★★ ()
Ответ на: комментарий от hobbit

Попробую приготовить к ней сюрприз для почтенной публики. Правда тут вопрос что считать годовщинйо - эту тему или собственно метапроговскую (эта 20 марта, метапрог - 21 марта). Или оба дня сразу? Как у нас день государственного флага 23 августа, а независимости - 24 августа.

metaprog ()
Ответ на: комментарий от stasolog

Потому что ты не осилил даже код написать верно - https://godbolt.org/z/yMoUDG Ты пытаешься читать мусор - что он там тебе будет выполнять сразу? Первую он выводит без выполнения функции.

Но в любом случае это не С++, а мусор какой-то. Подобное никому не интересно.

erevan ()
Ответ на: комментарий от erevan

Потому что ты не осилил даже код написать верно

Ну ошибся, с кем не бывает. Я правда ошибся вдвойне, и не совсем тот пример скинул, но я нашел в настоящем примере ту же ошибку, лол.

Но в любом случае это не С++, а мусор какой-то. Подобное никому не интересно.

Так вроде это ничем не отличается от вызова виртуальных функций из С++? Ну если прищуриться. Разве что размер может быть слишком большим. Ну и не расширишь enum извне.

stasolog ()
Последнее исправление: stasolog (всего исправлений: 1)
Ответ на: комментарий от stasolog

Так вроде это ничем не отличается от вызова виртуальных функций из С++? Ну если прищуриться. Разве что размер может быть слишком большим. Ну и не расширишь enum извне.

Дело не в этом. Дело в том, что в С++ ты вообще можешь исключить динамический диспатч. Тебе ненужно будет как в пту и всяких растах прикручивать енумы/юнионы/vtable для диспатча.

Точно так же у тебя есть таплы, в отличии от всякой раст-скриптухи. А где их нет - ты можешь просто прикрутить вариант, либо заколхоженный его аналог.

erevan ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.