2010-05-06 2 views
1

Я использую popen для выполнения команды под linux, а затем 4 process wile используют один и тот же вывод. Я пытаюсь дублировать дескриптор файла, чтобы передать его каждому процессу. вот мой код:Повторяющийся дескриптор файла после 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 этой работе плавник, после изменения всего = 4 он больше не работает. этот ответ слишком близко к тому, что мне нужно: link

+0

Действительно ли dup() возвращает -1? Вы пытались проверить errno? – Vereb

+0

Что именно вы подразумеваете под 'больше не работает'? Я догадываюсь, что ваши чтения терпят неудачу, а не 'dup' failing – Hasturkun

ответ

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

0

Прочитав вопрос, который вы связаны с, кажется, говорить о dup() и создания нового дескриптора файла, который полностью отделен от друг друга (они не разделяют файловое смещение между прочим). Если это то, что вы хотите, вам нужно будет сделать то, что они предлагают в вопросе.

Вам нужно будет открыть/повторно открыть вывод столько раз, сколько вы хотели бы иметь дубликаты. Похоже, что они работают вокруг ограничения, открывая новый файл, на который направлен выход. Я предполагаю, что вам просто нужно перенаправить вывод source_command в файл, а затем открыть выходной файл несколько раз, а не использовать dup().