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 child process, close read 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);
default:
/* We're the parent process, close write end of pipe */
close(p[1]);
return p[0];
}
}