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]); 를 해주면 될겁니다. 단방향파이프 하나로 하는것이니 안정성있게 작동하려면 하나의 연결관계만 존재해야 하므로 그런거죠.
... if((pid_t)0 == child) { /* child process */ close(1); /* close stdout */ if(-1 == (new_stdout = dup(pdes[1]))) die("dup()"); close (pdes[1]); close (pdes[0]); /* 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) */ close (pdes[1]); close (pdes[0]); ...댓글 달기