2010-05-06 187 views
1

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

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的IT工作鳍,改变总= 4后,不工作了。 这个答案太接近我所需要的: link

+0

dup()是否返回-1?你有没有试图检查errno? – Vereb 2010-05-06 12:24:22

+0

你是什么意思'不再工作'?我猜你的阅读失败,而不是'dup'失败 – Hasturkun 2010-05-06 13:13:27

回答

1

你目前的做法可能不会做你想做的。当你只是复制文件描述符时,它们都指向相同的管道 - 没有数据将会被复制。对于源命令发送的每个数据块,只有一个进程将读取它。

如果你要复制的数据(如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. */ 

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

+0

非常好,谢谢 – alaamh 2010-05-07 11:05:05

0

从阅读您链接到的问题,这似乎是在谈论dup()并创建一个新的文件描述符是从海誓山盟完全独立(不共享文件偏移等)。如果这是你想要的,你需要按照他们在问题中提出的建议去做。

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