【问题标题】:Duplicate file descriptor after popen弹出后重复的文件描述符
【发布时间】:2010-05-06 12:12:50
【问题描述】:

我在linux下使用popen执行命令,然后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);
    }

实际上,如果将 total 设置为 1 它可以正常工作,在更改 total = 4 后它不再起作用。 这个答案太接近我需要的了: link

【问题讨论】:

  • dup() 是否返回 -1?你试过检查errno吗?
  • does not work anymore 到底是什么意思?我猜你的阅读失败了,而不是 dup 失败

标签: c linux file-descriptor


【解决方案1】:

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

如果您想复制数据(如 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. */

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

【讨论】:

    【解决方案2】:

    从阅读您链接到的问题来看,它似乎是在谈论 dup() 并创建一个完全独立的新文件描述符(它们不共享文件偏移量等)。如果这是您想要的,您需要按照他们在问题中的建议进行操作。

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

    【讨论】:

      猜你喜欢
      • 2017-09-05
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 2011-10-30
      • 1970-01-01
      • 2017-07-08
      • 1970-01-01
      • 2021-03-12
      相关资源
      最近更新 更多