fgets的奇怪行为

时间:2013-07-19 19:49:23

标签: c block 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);
}

我的功能上面有什么不对吗?

2 个答案:

答案 0 :(得分:1)

它是因为无论写什么管道都没有刷出它的缓冲区。当你打印时,它最终会冲洗(尽管不会发生)。当你不打印时,管道实际上并没有被写入,因为它存储在内核缓冲区中直到它填满,然后内核将写入数据。在写入管道的进程中调用fdync或flush on pipe fd,以确保刷新内核缓冲区。

答案 1 :(得分:0)

在print-statement中添加换行符。它(可能)是行缓冲的,并且在遇到新行之前不会打印,而是调用fflush