2016-09-26 1 views
2

У меня есть исполняемый файл в Linux, который может взаимодействовать с stdin/stdout. Я пытаюсь написать программу на C++, которая может интерактивно вызывать эту программу, отправлять команды на свой stdin и записывать ее stdout.C++ Linux Interact Другая программа stdin/stdout

Я очень растерялся. Я не хочу раскошеливать свою программу (не так ли?). Я хочу, чтобы моя программа могла запускать «клиент», отправлять данные, получать выходные данные, отправлять больше данных, получать больше результатов и ... закрывать «клиент».

P.S. Да, я уверен, что это было задано раньше, но я потратил несколько часов на почесывание головы, возможно, не используя правильные ключевые слова.

+0

Вы хотите написать это, используя системные вызовы низкого уровня или можете использовать библиотеки? Один из вариантов - использовать [libexpect] (http://docs.activestate.com/activetcl/8.5/expect/libexpect.3.html) –

+0

@MarkPlotnick Это персональный проект, поэтому все, что облегчает это, - это путь , – CircuitGuy

+0

@MarkPlotnick На самом деле да, это работает очень хорошо! Я переключился на использование вызова exp_popen() из tcl8.6. Это открывает процесс и возвращает к нему дескриптор файла, который я могу читать/писать, как и любой другой файл. – CircuitGuy

ответ

3

Единственный способ выполнить другую программу - это один из системных вызовов exec(). Это единственный способ. И, как вы знаете, exec() заменяет исполняющую программу программой, заданной exec(). Процесс, который выпустил exec(), больше не будет существовать, это PID теперь используется новой программой.

Поэтому логически следует, что, если вы не хотите, чтобы ваша программа была заменена другим исполняемым файлом, ваша программа должна fork(), а дочерний процесс использует exec() для выполнения нового исполняемого файла. Это традиционный способ начать новый процесс и продолжить запуск исходного процесса. Для этого требуется A fork().

Ситуация вы описываете довольно типичны, краска-бай-зе-номера ситуации, что было сделано бесчисленное количество раз:

  1. Используйте трубу(), чтобы создать две трубы, одна для централизованному стандартного ввода, один для конвейера.

  2. Использовать fork(). Детский процесс dup2() s с конца считывания трубы stdin до 0, конец записи для канала stdout до 1, закрывает оба конца каждой из исходных труб и exec() - новый процесс.

  3. Родительский процесс закрывает считываемый конец труба stdin, конец записи в канале stdout, а затем переходит к взаимодействию с дочерним процессом, используя конец записи трубы stdin и конец считывания для канала stdout.

+0

Очень хорошее объяснение. Вы заполнили куски, которые только что проходили над моей головой в моих собственных исследованиях. Как в стороне, это похоже на ужасный интерфейс, который давно бы был заменен и отвлечен. Спасибо за помощь, хотя! – CircuitGuy

+0

@CircuitGuy Windows делает это лучше, верьте или нет. (Вы вызываете 'CreateProcess' и просто передаете ему дескрипторы, которые хотите, чтобы дочерний процесс использовался для stdin и stdout) – immibis

Смежные вопросы