Неблокирующая труба с использованием popen?

Я хотел бы открыть трубку, используя popen() и неблокирующий доступ для чтения.

Как я могу это достичь?

(Я обнаружил, что все блокирующие/синхронные)

Ответ 1

Настройка следующим образом:

FILE *f = popen("./output", "r");
int d = fileno(f);
fcntl(d, F_SETFL, O_NONBLOCK);

Теперь вы можете прочитать:

ssize_t r = read(d, buf, count);
if (r == -1 && errno == EAGAIN)
    no data yet
else if (r > 0)
    received data
else
    pipe closed

Когда все будет готово, очистка:

pclose(f);

Ответ 2

popen() внутренне вызывает pipe(), fork(), dup2() (чтобы указать дочерний процесс fds 0/1/2 в каналы) и execve(). Рассматривали ли вы их использование? В этом случае вы можете настроить канал, который вы считаете, неблокируемым, используя fcntl().

update: Здесь пример, только для иллюстративных целей:

int read_pipe_for_command(const char **argv)
{
   int p[2];

   /* Create the pipe. */
   if (pipe(p))
   {
      return -1;
   }

   /* Set non-blocking on the readable end. */
   if (fcntl(p[0], F_SETFL, O_NONBLOCK))
   {
      close(p[0]);
      close(p[1]);
      return -1;
   }

   /* Create child process. */
   switch (fork())
   {
      case -1:
          close(p[0]);
          close(p[1]);
          return -1;
      case 0:
          /* We're the parent process, close the writable part of the pipe */
          close(p[1]);
          return p[0];
      default:
          /* Close readable end of pipe */
          close(p[0]);
          /* Make stdout into writable end */
          dup2(p[1], 1);
          /* Run program */
          execvp(*argv, argv);
          /* If we got this far there was an error... */
          perror(*argv);
          exit(-1);
   }
}

Ответ 3

Никогда не пробовал, но я не понимаю, почему вы не смогли захватить дескрипторы файла с помощью fileno(), используйте fcntl(), чтобы установить неблокирование, и используйте read()/write(). Стоит попробовать.

Ответ 4

Вы просмотрели раздел "см. также" на странице man для popen()?

Быстрый поиск в Google показал эту страницу: http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#blocking Обсуждает блокировку и неблокирующий доступ к дескрипторам файлов.