popen后重复的文件描述符

时间:2010-05-06 12:12:50

标签: c linux file-descriptor

我使用popen在linux下执行命令,然后4个进程使用相同的输出。 我想再次复制文件描述符以将其传递给每个进程。 这是我的代码:

FILE* file_source = (FILE*) popen(source_command, "r");
int fd = fileno(file_source);
fdatasync(fd);

int dest_fd[4], y, total = 4;
    for (y = 0; y < total; y++) {
        dest_fd[y] = dup(fd);
    }

实际上,如果总设置为1,则它会起作用,在更改总数= 4后,它将不再起作用。 这个答案太接近我的需要了: link

2 个答案:

答案 0 :(得分:1)

您当前的方法可能无法达到您想要的效果。当您只复制文件描述符时,它们都引用相同的管道 - 没有数据将被复制。对于source命令发送的每个数据块,只有一个进程要读取它。

如果要复制数据(如tee实用程序那样),则需要明确这样做:

#define TOTAL 4

int dest_fd[TOTAL];
int dest_fd_wr[TOTAL];
int y;

/* Build pipes for reading the data from the child process */
for (y = 0; y < TOTAL; y++)
{
    int p[2];

    pipe(p);
    dest_fd[y] = p[0];
    dest_fd_wr[y] = p[1];
}

/* Create a child process to handle the "tee"-style duplication */
if (fork() == 0)
{
    /* Child process */
    FILE *file_source = popen(source_command, "r");
    FILE *file_sink[TOTAL];
    char buffer[2048];
    size_t nbytes;

    for (y = 0; y < TOTAL; y++)
    {
        close(dest_fd[y]);
        file_sink[y] = fdopen(dest_fd_wr[y], "w");
    }

    while ((nbytes = fread(buffer, 1, sizeof buffer, file_source)) > 0)
    {
        for (y = 0; y < TOTAL; y++)
        {
            fwrite(buffer, 1, nbytes, file_sink[y]);
        }
    }

    _exit(0);
}

for (y = 0; y < TOTAL; y++)
{
    close(dest_fd_wr[y]);
}

/* Now have a set of file descriptors in dest_fd[0..TOTAL-1] that each have
 * a copy of the data from the source_command process. */

错误处理留给读者练习;)

答案 1 :(得分:0)

通过阅读您链接的问题,它似乎在讨论dup()并创建一个完全独立的新文件描述符(它们之间不共享文件偏移)。如果这是你想要的,你需要做他们在问题中建议的内容。

您需要多次打开/重新打开输出,因为您需要重复输出。看起来他们通过打开输出所指向的新文件来解决限制。我的猜测是你只需要将source_command的输出重定向到一个文件,然后多次打开输出文件,而不是使用dup()