2012-09-30 7 views
1

저는 입니다.입니다. 나는 C로 작성된 리눅스 쉘을 작성했습니다. 지금 당장이 작업을하고 싶습니다. 다시 올라가서 지난 몇 주 동안 그걸로 땜질 받았다.루프에서 다중 파이프 실행

다음 코드의 경우 arrayOfCommands이라는 배열이 동적으로 채워집니다. 내 코드는 arrayOfCommands를 현재 실행중인 명령으로 채 웁니다. 필자의 예를 들어, 우리는 다음과 같은 명령을 수행 할 것이다 : ls -l | 화장실 및 arrayOfCommands이 따라 다음으로 가득 루프를하는 시간에이다 : 나는 이것을 실행하면

//PIPING 
int do_command(char **args, int pipes) { 
    // pipes is the number of pipes in the command 
    // (In our example, one) 


    // The number of commands is one more than the 
    // number of pipes (In our example, two) 
    const int commands = pipes + 1; //Ex: 2 
    int i = 0; 

    // Set up the pipes 
    int pipefds[2*pipes]; 

    for(i = 0; i < pipes; i++){ 
     if(pipe(pipefds + i*2) < 0) { 
      perror("Couldn't Pipe"); 
      exit(EXIT_FAILURE); 
     } 
    } 

    // Variables 
    int pid; 
    int status; 
    char *str_ptr; 

    int j = 0; 
    for (i = 0; i < commands; ++i) { 

     // A magic function that updates arrayOfCommands with 
     // the current command goes here. It doesn't make 
     // sense in the context of the code, so just believe me! :) 

     // Ex: The contents will be "ls -l" or "wc" depending on 
     // which time through the loop we are 

     pid = fork(); 

     if(pid == 0) { 
      //if not last command 
      if(i < commands){ 
       if(dup2(pipefds[j + 1], 1) < 0){ 
        perror("dup2"); 
        exit(EXIT_FAILURE); 
       } 
      } 

      //if not first command&& j!= 2*pipes 
      if(j != 0){ 
       if(dup2(pipefds[j-2], 0) < 0){ 
        perror("dup2"); 
        exit(EXIT_FAILURE); 
       } 
      } 

      for(i = 0; i < 2*pipes; i++){ 
        close(pipefds[i]); 
      } 

      // Should any of the below inputs be *arrayOfCommands or 
      // **arrayOfCommands or &arrayOfCommands? 
      // I'm REALLY bad with pointers 

      if(execvp(arrayOfCommands, arrayOfCommands) < 0){ 
        perror(arrayOfCommands); 
        exit(EXIT_FAILURE); 
      } 
     } 
     else if(pid < 0){ 
      perror("error"); 
      exit(EXIT_FAILURE); 
     } 

     j+=2; 
    } 

    for(i = 0; i < 2 * pipes; i++){ 
     close(pipefds[i]); 
    } 

    for(i = 0; i < pipes + 1; i++){ 
    } 
     wait(&status); 
} 

, 내가 얻을 :

여기
//Pass #1 
arrayOfCommands[]= ("ls", "-l", NULL) 

//Pass #2 
arrayOfCommands[]= ("wc", NULL) 

내가 지금까지 무엇을 가지고 오류의 몇 :

  • dup2가 : 잘못된 파일 설명
  • LS : | : 해당 파일이나 디렉토리
  • LS : 화장실 :

    1. 이러한 오류가 발생하는 이유는 무엇입니까 : 그런 파일이나 디렉토리는

은 누군가가 나에게 다음과 같은 두 가지를 알아내는 데 도움이되지 수 있을까요?

  • execvp 함수에서 포인터를 찾고 있다면 어떤 종류입니까? icommands -1 dup2가 해결해야 에 0에서 나가기 때문에

    //if not last command 
    if(i < commands) 
    

    if(i < commands -1) 
    

    같아야 arrayOfCommands *이 arrayOfArgs []를

  • +0

    Deja vu. 제발,이 읽어 : http : // stackoverflow.co.kr/questions/12657430/c-read-from-pipe-blocks-child-is-terminated/12661629 # 12661629 그런 다음 설명 된 절차를 따르십시오. – Serge

    답변

    2

    가 제일 먼저 숯불로 초기화 : 잘못된 파일 설명자

    ,451,515,

    LS : | : 해당 파일이나 디렉토리

    LS : 화장실 : 해당 파일이나 디렉토리

    은 잘못된 arrayOfCommands에 의해 발생합니다. 그것은 execvp(arrayOfCommands[0], arrayOfCommands)

    기본적으로 arrayOfCommandsint main(int argc, char** argv)의 동일한 형식 (일반적으로 argv) 당신의 인수 벡터의이어야 통해 각각

    char * arrayOfCommands[] = {"ls", "-l", NULL}; 
    

    char * arrayOfCommands[] = {"wc", NULL}; 
    

    에 의해 초기화 및 호출되어야한다 .

    +0

    Perfect! 감사! –