2013-07-19 22 views
0

我在這裏得到了一個阻止fgets的函數,但是當我在fgets之前打印某些東西時它並沒有阻塞。fgets的奇怪行爲

int exec_command(char *command, char *output_buf, int buf_size) 
{ 
    FILE* pipe = NULL; 

    char buffer[BUFFER_SIZE]; 
    char tmp[SMALL_BUFFER_SIZE]; 
    unsigned total_read = 0; 

    pipe = popen(command, "r"); 
    if(!pipe) 
    { 
     //Error 
     return -1; 
    } 

    memset(buffer, 0, sizeof(buffer)); 
    while(!feof(pipe)) 
    { 
     //printf("reading"); //If I uncomment this fgets doesnt block 
     if(fgets(tmp, sizeof(tmp), pipe) != NULL) 
     { 
      // check that it'll fit: 
      size_t len = strlen(tmp); 
      if (total_read + len >= sizeof(buffer)) 
       break; 

      // and add it to the big buffer if it fits 
      strcat(buffer, tmp); 
      total_read += len; 
     } 
    } 
    //Is there anything to copy 
    if (total_read) 
    strncpy (output_buf, buffer, buf_size); 

    return pclose(pipe); 
} 

上面的函數有什麼問題嗎?

+0

是的錯,你不關閉寫過程的結束,你也讀取。 –

+0

[popen(3) - Linux man page](http://linux.die.net/man/3/popen「)有用的信息。 – chux

+0

@Grijesh Chauhan - 你可以請你重述一下你的信息我不明白你發佈了什麼 – kuchi

回答

1

它是因爲無論寫你的管道是不是沖洗出它的緩衝區。當你打印時,它會結束沖洗(雖然不會發生)。當你不打印時,管道實際上並沒有被寫入,因爲它存儲在內核緩衝區中,直到它被填滿,然後內核將寫入數據。在寫入管道的進程中調用fsync或flush在管道fd上,以確保內核緩衝區被刷新。

+0

我調用的命令是ifconfig,當進程完成後它不會自動刷新管道嗎? – kuchi

+0

Ifconfig已經過時了,不,它不會在終止時自動刷新緩衝區 – Magn3s1um

+0

我剛剛使用了select()檢查流是否可讀解決此問題。無論如何感謝提醒我,ifconfig是過時的:) – kuchi

0

在打印語句中添加一個新行。它可能(可能)是行緩衝的,直到遇到換行時纔會打印,請致電fflush