2012-07-04 5 views
0

저는 C 언어를 처음 사용하며 오늘 popen 함수를 사용하여 만든 "Open Stream"을 닫으려고 할 때 문제가 발생합니다. 1.이 프로그램에서 사용한 폴 기능 때문에이 문제가 발생합니까? 2. 또는 fcntl 함수 때문에? 누군가가 내게이 문제의 정확한 원인을 가르쳐 준다면 나는 매우 기쁠 것입니다. 아래 코드 샘플을 첨부하려고합니다.popen을 사용하여 파일을 닫을 수 없습니다.

코드 샘플 :

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

char line[1024]; 
FILE *tfd; 

int readData(int *fd) 
{ 
    struct pollfd pfd; 
    int pollTime = 10000; 
    pfd.events = POLLIN; 
    pfd.fd = *fd; 
    int ret=1; 

    ret = poll(&pfd,1,pollTime); 
    printf("\nAfter ret=%d\n.",ret); 
    if(ret == -1 || ret ==0) 
     { 
       printf("Couldn't poll returned : %d\n", ret); 
       return 0; 
     } else { 
       if(fgets(line,sizeof(line),tfd) == NULL) 
       { 
         printf("\nReturns nothing."); 
         return 0; 
       } 
       printf("\nRead Some data."); 
     } 
     return ret; 
} 


void main(void) 
{ 
     int ret; 
     int fd, flags; 
     char filepath[] = "/home/TEST/"; 
     char filename[] = "log.txt"; 
     char cmd[100]; 

     sprintf(cmd,"tail -f %s%s",filepath, filename); 
     tfd = popen(cmd, "r"); 
     fd = fileno(tfd); 

     flags = fcntl(fd, F_GETFL, 0); 
     flags |= O_NONBLOCK; 
     fcntl(fd, F_SETFL, flags); 

     if(tfd==NULL) 
     { 
       printf("\npopen failed, exiting.\n"); 
       exit(0); 
     } 
     while((ret=readData(&fd)) > 0) 
     { 
       printf("\nret2=%d.",ret); 
       printf("\nLine : %s",line); 
     } 
     printf("\n**********DONE****************.\n"); 
     pclose(tfd); 
} 

출력 :

[[email protected] TEST]# ./polltail 

After ret=1 
. 
Read Some data. 
ret2=1. 
Line : 64 bytes from maa03s05-in-f4.1e100.net (74.125.236.68): icmp_req=31 ttl=52 time=38.4 ms 

After ret=0 
.Couldn't poll returned : 0 

**********DONE****************. 

여기 내가 실행의 끝 부분에 나타나는 프롬프트를 기대하고있다. 그러나 그것은 오지 않을 것입니다.

답변

1

꼬리가 10 초 동안 출력을 생성하지 않았기 때문에 시간 초과가 발생했습니다. 그런 다음 pclose()를 호출합니다. 그러나 이것은 설명서에서 pclose()에 대한 내용입니다.

pclose() 함수는 관련 프로세스가 종료 될 때까지 대기하고 wait4 (2)가 반환 한 명령의 종료 상태를 반환합니다.

tail 명령은 여전히 ​​실행 중이며 누군가가 그것을 죽일 때까지 계속 실행되므로 pclose()가 무기한 차단됩니다. 실행중인 tail 명령을 죽이기 위해 프로그램이 필요하면 popen/pclose를 사용하는 것보다 다른 접근법이 필요합니다.

+0

안녕하세요, 매우 빠른 응답을 보내 주셔서 감사합니다. 스트림 파일을 닫기 전에이 꼬리 pid를 가져 오거나이 꼬리 처리를 어떻게 죽일 수 있습니까? – Sougrakpam

+1

fork()/exec()를 사용하여 자식 프로그램을 직접 만들고 실행하고 pipe() 및 dup2()를 사용하여 자식 프로그램의 stdin/out/err과 통신하도록 filedescriptors를 설정해야합니다. 예제를 포함하고 그러한 개념을 설명하기 때문에 유닉스 프로그래밍에 관한 책이 가장 적합 할 것이다. – nos

1

-f 옵션을 사용하면 파일 끝이 에 도달 할 때 tail이 멈추지 않고 입력이 에 추가 될 때까지 기다릴 수 있습니다. 표준 입력이 파이프이면 -f 옵션은 무시되지만 FIFO 인 경우에는 무시됩니다.

pclose() 함수는 관련 프로세스가 종료 될 때까지 대기합니다. 그것 wait4 (2)에 의해 반환 된 명령의 종료 상태를 반환합니다.

만일 pclose() 함수는 -1을 리턴 스트림은 이미 "pclosed"만일 스트림하는 "popened"명령과 연관되어 있지 않은 경우, 또는 만일 wait4 (2) 가 에러를 반환하는 경우.

pclose()의 반환 값을 확인하십시오.

+0

안녕하세요. 매우 빠른 응답을 보내 주셔서 감사합니다. 스트림 파일을 닫기 전에이 꼬리 pid를 가져 오거나이 꼬리 처리를 어떻게 죽일 수 있습니까? – Sougrakpam

관련 문제