2017-05-14 5 views
0
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <fcntl.h> 

int main(void) { 
    int pfd1[2]; 
    int pfd2[2]; 
    pid_t pid1, pid2, pid3; 
    if(pipe(pfd1)==-1) { 
     perror("Creazione pipe"); 
     exit(EXIT_FAILURE); 
     } 
    if(pipe(pfd2)==-1) { 
     perror("Creazione pipe"); 
     exit(EXIT_FAILURE); 
     } 
    printf("Sono il padre\n"); 
    switch(pid1=fork()) { 
     printf("%d\n", pid1); 
     case -1: { 
      perror("Creazione figlio 1"); 
      exit(EXIT_FAILURE); 
      } 
     case 0: { //figlio 1 
      printf("Sono il figlio 1\n"); 
      if(dup2(pfd1[1],1)==-1) { //redirige lo stdout sul descrittore scrittura 
       perror("Prima redirezione"); 
       exit(EXIT_FAILURE); 
       } 
      close(pfd1[0]); 
      close(pfd1[1]); //lo chiudo perchè sto redirigendo lo stdout 
      close(pfd2[0]); 
      close(pfd2[1]); 
      execlp("ps", "ps", "-A", "-ostat,pid", (char*) NULL); 
      } 
     } 
    waitpid(pid1,NULL,0); 
    switch(pid2=fork()) { 
     case -1: { 
      perror("Creazione figlio 2"); 
      exit(EXIT_FAILURE); 
      } 
     case 0: { //figlio 2 
      printf("Sono il figlio 2\n"); 
      if(dup2(pfd1[0],0)==-1) { //redirige lo stdin sul descrittore lettura 
       perror("Seconda redirezione"); 
       exit(EXIT_FAILURE); 
       } 
      printf("Prima redirezione figlio 2\n"); 
      if(dup2(pfd2[1],1)==-1) { 
       perror("Terza redirezione"); 
       exit(EXIT_FAILURE); 
       } 
      close(pfd1[1]); 
      close(pfd1[0]); 
      close(pfd2[0]); 
      close(pfd2[1]); 
      execlp("grep", "grep", "-e", "[zZ]", (char*) NULL); 
      } 
    waitpid(pid2, NULL,0); 
    switch(pid3=fork()) { 
     case -1: { 
      perror("Creazione terzo figlio"); 
      exit(EXIT_FAILURE); 
      } 
     case 0: { //figlio 3 
      printf("Sono il figlio 3\n"); 
      if(dup2(pfd2[0],0)==-1) { 
       perror("Quarta redirezione"); 
       exit(EXIT_FAILURE); 
       } 
      close(pfd1[0]); 
      close(pfd1[1]); 
      close(pfd2[0]); 
      close(pfd2[1]); 
      execlp("awk", "awk", "'{print $2}'", (char*) NULL); 
      } 
     } 
    /*padre*/ 
    //waitpid(pid1, NULL, 0); 
    //waitpid(pid2, NULL, 0); 
    waitpid(pid3, NULL, 0); 
    close(pfd2[0]); 
    close(pfd2[1]); 
    close(pfd1[0]); 
    close(pfd1[1]); 
    return 0; 
    } 

} 

こんにちは、 システムコールdup2を使用してシェルbashコマンドのパイプを作成しようとしています。 私が期待する出力は、私は3人の子供をフォークし、それらを2本のパイプを介して通信を行うことされて何dup2でパイプを作成する

bash $> ps -A -ostat,pid | grep -e [zZ] | awk '{print $2}' 

と同じでなければなりません。子のそれぞれは、コマンドの一部を実行します。 問題は私のプログラムが明らかにexecをやらなくなった2番目の子供に突っ込まれてしまうことです。 私のコードにはいくつかの問題があると確信していますが、私がdup2を使用しようとしているのは初めてです。少し混乱しています。 また、printfsは気にしないでください。デバッグ用です。 ありがとう!

答えて

0

基本的に正しい位置でパイプを閉じる必要があり、switch文でブラケットを閉じることができませんでした。コードは次のとおりです。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <sys/wait.h> /*lib for waitpid()*/ 

int main(void) { 
    int pfd1[2]; 
    int pfd2[2]; 
    pid_t pid1, pid2, pid3; 
    if(pipe(pfd1)==-1) { 
     perror("Creazione pipe"); 
     exit(EXIT_FAILURE); 
     } 
    if(pipe(pfd2)==-1) { 
     perror("Creazione pipe"); 
     exit(EXIT_FAILURE); 
     } 
    printf("Sono il padre\n"); 
    switch(pid1=fork()) { 
     printf("%d\n", pid1); 
     case -1: { 
      perror("Creazione figlio 1"); 
      exit(EXIT_FAILURE); 
      } 
     case 0: { //figlio 1 
      printf("Sono il figlio 1\n"); 
      if(dup2(pfd1[1],1)==-1) { //redirige lo stdout sul descrittore scrittura 
       perror("Prima redirezione"); 
       exit(EXIT_FAILURE); 
       } 
      close(pfd1[0]); 
      close(pfd1[1]); //lo chiudo perchè sto redirigendo lo stdout 
      close(pfd2[0]); 
      close(pfd2[1]); 
      execlp("ps", "ps", "-A", "-ostat,pid", (char*) NULL); 
      } 
     } 
    waitpid(pid1,NULL,0); 
    switch(pid2=fork()) { 
     case -1: { 
      perror("Creazione figlio 2"); 
      exit(EXIT_FAILURE); 
      } 
     case 0: { //figlio 2 
      printf("Sono il figlio 2\n"); 
      if(dup2(pfd1[0],0)==-1) { //redirige lo stdin sul descrittore lettura 
       perror("Seconda redirezione"); 
       exit(EXIT_FAILURE); 
       } 
      printf("Prima redirezione figlio 2\n"); 
      if(dup2(pfd2[1],1)==-1) { 
       perror("Terza redirezione"); 
       exit(EXIT_FAILURE); 
       } 
      close(pfd1[0]); 
      close(pfd1[1]); 
      close(pfd2[0]); 
      close(pfd2[1]); 
      execlp("grep", "grep", "-e", "[Ss]", (char*) NULL); 
      } 

    } /*You forgot that bracket*/ 
    /* 
    * Close the pipe before waitpid because 2rd child 
    * will wait until you close it. Check pipe theory 
    */ 
    close(pfd1[1]); 
    close(pfd1[0]); 
    waitpid(pid2, NULL,0); 
    switch(pid3=fork()) { 
     case -1: { 
      perror("Creazione terzo figlio"); 
      exit(EXIT_FAILURE); 
      } 
     case 0: { //figlio 3 
      printf("Sono il figlio 3\n"); 
      if(dup2(pfd2[0],0)==-1) { 
       perror("Quarta redirezione"); 
       exit(EXIT_FAILURE); 
       } 
      close(pfd2[0]); 
      close(pfd2[1]); 
      /*' ' removed from the "{print $2}"*/ 
      execlp("awk", "awk", "{print $2}", (char*) NULL); 
      } 
    } 
    /* 
    * Close the pipe before waitpid because 3rd child 
    * will wait until you close it. Check pipe theory 
    */ 
    close(pfd2[0]); 
    close(pfd2[1]); 
    waitpid(pid3, NULL, 0); 


    return 0; 
    } 
関連する問題