pipe & fork & execlp & fgets 관련 문의 드립니다.
글쓴이: seongwon1 / 작성시간: 수, 2014/02/12 - 4:40오후
안녕하세요.
아래와 같이 2개의 process를 만들어서 자식 process에서 찍은 결과 (ls -al의 결과)를
부모 process에서 출력하는 예제를 만들어 봤습니다.
그런데 문제가 있는데요 부모 process에서 ls -al의 결과물을 모두 찍은 후
fgets()에서 계속 wait 을 하네요.
fgets()가 eof나 error일 경우 NULL을 return 할터인데,
fgets의 입력 stream이 stdin이기 때문에 eof를 만나지 못해서 계속 대기중인 건지...
어떻게 하면 해결할 수 있는지 가르침 부탁 드립니다.
감사합니다.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define SIZE_BUF 4096 /*function prototypes */ void die(const char*); int main(int argc, char **argv) { int pdes[2], new_stdin, new_stdout; pid_t child, child_1, child_2; char *buf=NULL, *ret=NULL; int str_len; char buf_flag[16]={0,}; char buf_name[128]={0,}; FILE *fp = NULL; int status, result; if(-1 == (pipe(pdes))) die("pipe()"); if((pid_t)-1 == (child = fork())) die("fork()"); if((pid_t)0 == child) { /* child process */ close(1); /* close stdout */ if(-1 == (new_stdout = dup(pdes[1]))) die("dup()"); /* now stdout and pdes[1] are equivalent (dup returns lowest free descriptor) */ if(-1 == (execlp("ls", "ls", "-al", NULL))) exit(EXIT_SUCCESS); } else { /* parent process */ close(0); /* close stdin */ if(-1 == (new_stdin = dup(pdes[0]))) die("dup()"); /* now stdin and pdes[0] are equivalent (dup returns lowest free descriptor) */ buf = (char *)calloc(sizeof(char), SIZE_BUF); if(!buf) { close(pdes[0]); die("calloc()"); } fp = fdopen(new_stdin, "r"); if(!fp) { free(buf); die("fdopen()"); } while(fgets(buf, SIZE_BUF, fp) != NULL) { printf("Result : %s", buf); } free(buf); fclose(fp); } finish : return 0; } void die(const char *msg) { perror(msg); exit(EXIT_FAILURE); }
Forums:
popen()을 쓰니 해결이 되는 것 같습니다...
http://stackoverflow.com/questions/149860/how-to-prevent-fgets-blocks-when-file-stream-has-no-new-data
위의 경우 dup후에 부모와 자식 모두에서 close
위의 경우 dup후에 부모와 자식 모두에서 close (pdes[1]); close (pdes[0]); 를 해주면 될겁니다. 단방향파이프 하나로 하는것이니 안정성있게 작동하려면 하나의 연결관계만 존재해야 하므로 그런거죠.
댓글 달기