2013-09-10 3 views
1

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

#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; 
} 

ответ

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 { //... 
Смежные вопросы