2010-05-06 185 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()