Передача данных от родителя к ребенку и обратно с помощью Unix C

Я очень новичок в C и пытаюсь научиться использовать каналы для передачи данных из родительского процесса в дочерний процесс и наоборот в среде Unix. В приведенном ниже коде я получаю аргумент командной строки и строю массив символов на основе значения аргумента. Затем я использую каналы для передачи массива символов дочернему элементу, который будет выполнять программу под названием vc. Эта программа возвращает результат на основе массива char. Мой вопрос: как я могу использовать второй канал, чтобы вернуть результат родительскому? Кроме того, как только родитель имеет его, как я могу напечатать его на экране, так как родительский элемент настроен на отправку вывода дочернему устройству? Спасибо.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys wait.h="">

int main(int argc,char *argv[])
{
 int 
 pfildes[2],
 pid,
 argNumber;
 char
 buffer[256],
 charString[1024]; 
 //Check for arguments 
 if(argc != 2) {
 printf("No command line arguements given.\n");
 argNumber=10; //default
 }
 else
 argNumber=atoi(argv[1]);

 //***********************************
 //Build charString based on argNumber
 //*********************************** 

 //create pipes
 if(pipe(pfildes) == -1) {
 //error occured when creating pipe
 perror("demo");
 exit(1);
 }
 //create child process
 if((pid=fork()) < 0) {
 //error occured when forking child
 perror("demo");
 exit(1);
 }
 else if(pid > 0) {
 //parent process
 close(pfildes[0]);
 dup2(pfildes[1],1);
 printf("%s", charString);

 close(pfildes[1]);

 perror("demo");
 _exit(1);
 }
 else {
 //child process
 close(pfildes[1]);
 dup2(pfildes[0],0);
 execlp("/usr/bin/vc","vc", NULL);
 close(pfildes[0]);

 perror("demo");
 exit(1);
 }

 while(wait(NULL) >0);
 return 0;
}
</sys></unistd.h></string.h></stdlib.h></stdio.h>
1 ответ

Вы можете использовать socketpair() вместо pipe() для создания двунаправленного канала связи между родительским и дочерним процессом:

//...
if (socketpair(PF_UNIX, SOCK_STREAM, 0, pfildes) == -1) {
 //error occured when socket pair
 perror("demo: socketpair");
 exit(1);
}
//..

В дочернем процессе вы можете dup() одну из пары на вход и вывод перед вызовом exec():

//...
else {
 //child process
 close(pfildes[1]);
 dup2(pfildes[0],0);
 dup2(pfildes[0],1);
 dup2(pfildes[0],2);
 close(pfildes[0]);
 execlp("/usr/bin/vc","vc", NULL);
 perror("demo: child exec");
 exit(1);
}
//...

В родительском процессе вы можете создать FILE * из файлового дескриптора, используя fdopen(), поэтому вам не нужно dup() над существующим дескриптором файла stdout:

//...
else if(pid > 0) {
 //parent process
 close(pfildes[0]);
 FILE *to_child = fdopen(dup(pfildes[1]), "w");
 FILE *from_child = fdopen(dup(pfildes[1]), "r");
 close(pfildes[1]);
 fprintf(to_child, "%s", charString);
 while (fgets(buf, sizeof(buf), from_child) != NULL) {
 //...do something with output
 }
 //...
} else { //...

licensed under cc by-sa 3.0 with attribution.