C: открытое чтение из блоков stdout - PullRequest
1 голос
/ 08 июня 2019

Страница man для popen говорит, что «чтение из« всплывающего »потока читает стандартный вывод команды».

Однако я не могу получить вывод подпроцесса втривиальная программа ниже.Родительский процесс «читатель» блокирует чтение (с использованием fgets или fread)

Чего мне не хватает?

Присоединение к программе pinger сGDB показывает, что он зацикливается и вызывает printf для вывода текста.Просто ничего не обнаружено fgets на стороне родителя ...

PINGER.C

#include <string.h>
#include <stdio.h>
#include <unistd.h>

int
main(int argc, char **argv)
{
    int i = 0;
    while (1)
    {
        printf("stdout %d\n", i++);
        sleep(1);
    }
}

POPENTEST.C

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>


int
main(int argc, char **argv)
{
    char *cmd = "./pinger";
    printf("Running '%s'\n", cmd);

    FILE *fp = popen(cmd, "r");
    if (!fp)
    {
        perror("popen failed:");
        exit(1);
    }

    printf("fp open\n");

    char inLine[1024];
    while (fgets(inLine, sizeof(inLine), fp) != NULL)
    {
        printf("Received: '%s'\n", inLine);
    }

    printf("feof=%d ferror=%d: %s\n", feof(fp), ferror(fp), strerror(errno));
    pclose(fp);
}

ВЫХОД

$ ./popenTest
fp open

1 Ответ

1 голос
/ 08 июня 2019

По умолчанию буферы C записывают в стандартный вывод, когда стандартный вывод не подключен к tty.Это означает, что с точки зрения ОС, программа не записывала ничего в стандартный вывод, пока либо буфер не будет заполнен, либо вы вручную сбросите вывод:

#include <string.h>
#include <stdio.h>
#include <unistd.h> 

int
main(int argc, char **argv)
{
    int i = 0;
    while (1)
    {
        printf("stdout %d\n", i++);
        fflush(stdout);
        sleep(1);
    }
}

При подключении к tty стандартный вывод автоматически очищаетсяна каждой новой строке.Но эта автоматическая промывка не происходит, когда стандартный вывод подключен к трубе.

...