Fork (), Dup2 (), Pipe (), Exe c () все вместе - PullRequest
0 голосов
/ 24 апреля 2020

Я пытаюсь написать программу, в которой родитель считывает из файла пары чисел, и для каждой строки родитель отправляет пару дочернему элементу (через канал), дочерний элемент вычисляет наибольший общий делитель (используя отдельный файл exe c), а затем возвращает gcd родительскому элементу по каналу. Я думаю, что у меня есть проблема с дуплом, я не очень понимаю, в чем проблема. Я думаю, что мне нужно сделать 2 дублирования, один на дочернем и один на родительском, хотя я не уверен, какой fd мне нужно использовать для каждого дублирования, и каков вывод файла с использованием exe c.

Родитель:

    if (p > 0) {

        if (close(fd1[0]) == -1)
            perror("fd1 reading end");

        if (write(fd1[1], numbers, sizeof(numbers) + 1) == -1) // writing 2 numbers to pipe 1 as an array
            perror("Error writing to pipe 1");

        if (close(fd1[1]) == -1)
            perror("fd1 writing end");

        char gcd[BUF_SIZE];

        if (close(fd2[1]) == -1)
            perror("fd2 writing end");

        wait(NULL);



        if (read(fd2[0], gcd, sizeof(gcd)) == -1)
            perror("Reading from pipe2");

        if (close(fd2[0]) == -1)
            perror("fd2 reading end");

        printf("%d\t%d\tgcd: %d\n", numbers[0], numbers[1], atoi(gcd));

    }

Ребенок:

        if (p == 0) {
        int numbersFromParent[2];

        if (close(fd1[1]) == -1) {  // fd1 writing end
            perror("fd1 writing end");
            _exit(1);
        }
        if (close(fd2[0]) == -1) { // fd2 reading end
            perror("fd2 reading end");
            _exit(1);
        }

        numRead = read(fd1[0], numbersFromParent,
                sizeof(numbersFromParent)); // Reading 2 numbers from parent as an array
        if (numRead == -1) {
            perror("Reading pipe 1");
            _exit(1);
        }
        if (numRead == 0) {
            printf("equals 0, dunno why\n");
            _exit(1);
        }

        /* Since args aceepting strings I need to convert the ints */
        char num1[INT_SIZE];
        char num2[INT_SIZE];

        sprintf(num1, "%d", numbersFromParent[0]);
        sprintf(num2, "%d", numbersFromParent[1]);
        /* End of conversion */

        if (close(fd1[0]) == -1) {
            perror("fd1 reading end");
            _exit(1);
        }

        char *args[] = { "./Child", num1, num2, NULL };

        if (dup2(fd2[1], 1) < 0) {
            perror("Unable to dup");
            exit(EXIT_FAILURE);
        }

        if (close(fd2[1]) == -1)
            perror("fd2 writing end");

        if (execv(args[0], args) == -1) { // calculate gcd and send via fd2 to parent
            perror("Exec failed!");
        }

        _exit(EXIT_SUCCESS);

    }

Вывод:

11  33  gcd: 11
25  35  gcd: 51
14  42  gcd: 14
30  68  gcd: 24

Дочерний файл для exe c:

    int gcd(int a, int b) {
    if (a == 0)
        return b;
    return gcd(b % a, a);
}

int main(int argc, char **argv) {

    int myGcd = gcd(atoi(argv[1]), atoi(argv[2]));
    printf("%d", myGcd);
}

есть намеки? чаевые? советы?

...