2017-11-07 2 views
0

메인 프로그램에서 보조 프로그램을 실행하기 위해 메인 프로그램을 실행하는 두 개의 프로그램 (main과 aux)을 만들어야합니다. 부모는 빈 줄 '\ n'까지 사용자로부터 입력을받으며 자식은 aux를 실행하여 입력을 다시 인쇄합니다. execlp() 대신 주석이 달린 코드로 main에서 작동하도록 할 수는 있지만 execlp (aux)가 제대로 작동하지는 않습니다. 어떤 도움을 주셔서 감사합니다.C - 하나의 프로그램에서 다른 프로그램으로 파이프 입력

"main.c에"

#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 

int main() { 
    int fd[2], i; 
    char line[100], buffer[100]; 

    pipe(fd); 

    pid_t pid = fork(); 

    if (pid < 0) { 
      printf("Fork Failed\n"); 
      exit(-1); 
    } 
    else if (pid > 0) { 
      close(fd[0]); 
      while(fgets(line, sizeof(line), stdin) && line[0] != '\n') { 
        write(fd[1], line, sizeof(line)); 
      } 
      close(fd[1]); 
    } 
    else { 
      close(fd[1]); 
      dup2(fd[0], STDIN_FILENO); 

      //while(read(fd[0], buffer, sizeof(buffer))) 
      //  printf("> %s", buffer); 

      execlp("./aux", "aux", (char *)0); 
    } 
    return 0; 
} 

"aux.c"

#include <stdio.h> 
#include <stdlib.h> 

int main() { 
    char data[100]; 

    while(fgets(data, sizeof(data), stdin)) 
      printf(">%s\n", data); 

    return 0; 
} 

샘플 입력/출력

this 
>this 

is a test 
> 
> test 

only prints larger text with random \n 
> 
>ts larger text with random \n 
+1

안녕하세요, 원본 이미지를 완전히 대체하는 exec *() 패밀리로 새 이미지를 실행하고 있습니다. 프로그램 텍스트, 힙, 스택 등과 비슷합니다. –

+0

[ALP] (http://www.makelinux.net/alp/)와 [execve (2)]와 같은 매뉴얼 페이지 (http://man7.org/linux/man -pages/man2/execve.2.html) –

+0

모든 경고와 디버그 정보로 컴파일 :'gcc -Wall -Wextra -g' 그러면 디버거'gdb' **와 [strace (1)] (http : //man7.org/linux/man-pages/man1/strace.1.html). 디버깅'printf'를 추가하십시오. 'execlp'가 실패하지 않았는지 확인하십시오 (예 :'perror ("execlp");'....) –

답변

0

write(2)에 대한 귀하의 호출은 write 100 항상 (당신 잘못 바이트도 짧음 line -s) :

당신이 line 버퍼 만 작성 바이트, 항상 100 바이트 (그들 중 일부는하지 초기화되고)마다 작성하려는 때문에
   write(fd[1], line, sizeof(line)); // WRONG 

아마 strlen(3)

  size_t ll = strlen(line); 
      ssize_t wc = write(fd[1], line, ll); 
      if (wc != ll) 
       fprintf(stderr, "write was wrong (only %d, wanted %d) - %s\n", 
         (int) wc, (int) ll, strerror(errno)); 

를 사용해야합니다. 주의 깊게 모든 사용 기능 (또한 ALP 또는 Unix/POSIX/리눅스 프로그래밍에 대한 다른 책)의 설명서를 읽어 보시기 바랍니다 char data[100];

선언 이후 귀하의 경우 sizeof(data)

는 100입니다. 당신은 더 큰 버퍼 (예를 들어 4KB이다 각각 적어도 효율성을 사용하여 선호한다 (stdio(3)없이) read(2) 직접 write(2)을 사용하려는 경우,

#include <string.h> 
    #include <errno.h> 

을 실제로 : strerror(3)errno(3)의 설명서를 추가 할 필요가 있음을 알려줍니다) 그리고 부분 read -s 및 write -s를 관리하고 직접 버퍼링해야합니다.

모든 경고와 디버그 정보를 사용하여 컴파일하고 use the gdb debuggerstrace(1) (및 valgrind)을 배우십시오. 일반적으로 scaredundefined behavior입니다 (그러나 언뜻보기에는 프로그램에 UB가없는 것 같습니다).

execlp(3)이 실패 할 수 있습니다. 그 다음에 perror(3)에 전화를 걸어보십시오.

+0

고마워요! strlen이 바로 잡았어. 나는 또한 당신이 오류 검사에 언급 한 Basile Starynkevitch와 Jonathan Leffler가 작성한 코드를 넣었습니다. 이것은 제가 처음으로 사용하는 C 클래스이며, 교수는 결코 gdb 디버거를 사용하지 않았습니다. 나는 그것을 조사 할 것이다. 모두에게 다시 한 번 감사드립니다. –

+0

'gdb'를 어떻게 사용하는지 반드시 배워야합니다. 그것의 문서는 좋은 튜토리얼 페이지를 가지고있다. –

관련 문제