Дубликат файлового дескриптора после открытия

Я использую 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);
    }

на самом деле, если для total установлено значение 1, оно работает плавно, после изменения total = 4 оно больше не работает. этот ответ слишком близок к тому, что мне нужно: ссылка


person alaamh    schedule 06.05.2010    source источник
comment
Возвращает ли dup() -1? Вы пробовали проверить errno?   -  person Vereb    schedule 06.05.2010
comment
Что именно вы подразумеваете под does not work anymore? Я предполагаю, что ваши чтения терпят неудачу, а не dup   -  person Hasturkun    schedule 06.05.2010


Ответы (2)


Ваш текущий подход, вероятно, не будет делать то, что вы хотите. Когда вы просто дублируете файловые дескрипторы, все они ссылаются на один и тот же канал — никакие данные не будут дублироваться. Каждый блок данных, отправленный исходной командой, будет прочитан ровно одним процессом.

Если вы хотите дублировать данные (как это делает утилита 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. */

Обработка ошибок оставлена ​​в качестве упражнения для читателя ;)

person caf    schedule 07.05.2010

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

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

person dlamotte    schedule 06.05.2010