Дубликат файлового дескриптора после всплывающего окна - PullRequest
1 голос
/ 06 мая 2010

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

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

Ответы [ 2 ]

1 голос
/ 07 мая 2010

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

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

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

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

...