fork () общение с детьми с трубками - PullRequest
0 голосов
/ 12 мая 2019

У меня проблема с общением с отцом и детьми в течение полутора недель. Мне удалось помочь сработать между отцом и ребенком, но когда я добрался до двух и трех детей, у меня не получилось.

Я хочу в каждом execv возвращать символ '1' или '0' в массив символов отца.

Я пытался нарисовать направления каналов и копии dup (), но я всегда получаюзастрял и его вид спагетти-кода для меня, и я могу с уверенностью отследить, где проблема.

вот код.если кто-то сможет это исправить и объяснить мне, это будет более чем приветствоваться.еще раз спасибо!.

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>

#define SIZE 81
#define EXEC "./child"
#define EXEC2 "./child2"
int main(int argc, char *argv[])
{
    char charMatrix[SIZE] =
    { 0 };
    int matrix[9][9] =
    { 0 };
    char chilesStatus[3] =
    { 0 };
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s matrix file \n", argv[0]);
        exit(EXIT_FAILURE);
    }

    int fdr = open(argv[1], O_RDONLY);
    if (fdr < 0)
    {
        perror("failed to open input or output files");
        exit(EXIT_FAILURE);
    }

    char c;
    int k = 0;
    while (read(fdr, &c, 1) == 1 && k < (int) sizeof(charMatrix))
    {
        if (c != ' ' && c != '\n')
            charMatrix[k++] = c - '0';
    }

    close(fdr);

    int index = 0;
    for (int i = 0; i < 9; i++)
    {
        for (int j = 0; j < 9; j++)
            matrix[i][j] = charMatrix[index++];
    }

    printf("Input matrix:\n");
    for (int i = 0; i < 9; i++)
    {
        printf("P: ");
        for (int j = 0; j < 9; j++)
            printf(" %d", matrix[i][j]);
        printf("\n");
    }
    fflush(stdout); // Making sure output is flushed even if it is going to a pipe

    int pipe1[2];
    int pipe2[2];

    if (pipe(pipe1) == -1 || pipe(pipe2) == -1) //pipe validation
    {
        perror("Pipe failed");
        exit(EXIT_FAILURE);
    }

    pid_t Child = fork();
    if (Child < 0)
    {
        perror("Fork failed");
        exit(EXIT_FAILURE);
    }

    if (Child == 0)
    {
        close(pipe1[0]);
        dup2(pipe1[1], STDOUT_FILENO);
        close(pipe1[1]);
        //close(pipe1[1]);
        // dup2(pipe1[1], STDOUT_FILENO);
        //close(pipe2[0]);

        execl(EXEC, EXEC, NULL);
        int errnum = errno;
        fprintf(stderr, "Failed to execute '%s' (%d: %s)\n", EXEC, errnum,
                strerror(errnum));
        exit(EXIT_FAILURE);
    }
    Child = fork();
    if (Child == 0)
    {
        close(pipe1[1]);
        dup2(pipe1[0], STDIN_FILENO);
        close(pipe1[0]);

        close(pipe2[0]);
        dup2(pipe2[1], STDOUT_FILENO);
        close(pipe2[1]);

        execl(EXEC2, EXEC2, NULL);
        int errnum = errno;
        fprintf(stderr, "Failed to execute '%s' (%d: %s)\n", EXEC, errnum,
                strerror(errnum));
                exit(EXIT_FAILURE);
    }
    Child = fork();
    if (Child == 0)
        {
            close(pipe1[0]);
            close(pipe1[1]);
            close(pipe2[1]);
            dup2(pipe2[0], 0);
            close(pipe2[0]);

            execl(EXEC2, EXEC2, NULL);
            int errnum = errno;
            fprintf(stderr, "Failed to execute '%s' (%d: %s)\n", EXEC, errnum,
                    strerror(errnum));
                    exit(EXIT_FAILURE);
        }
      close(pipe1[0]);
      close(pipe1[1]);
      close(pipe2[0]);
      close(pipe2[1]);
    if (write(pipe1[1], charMatrix, sizeof(charMatrix)) != sizeof(charMatrix))
    {
        perror("failed to write to child");
        exit(EXIT_FAILURE);
    }
    if (write(pipe1[2], charMatrix, sizeof(charMatrix)) != sizeof(charMatrix))
    {
        perror("failed to write to child");
        exit(EXIT_FAILURE);
    }

    char result[3];
    int nbytes = read(pipe2[0], &result, sizeof(result));
    if (nbytes <= 0 )
    {
        perror("Failed to read from pipe");
        exit(EXIT_FAILURE);
    }


    int corpse;
    int status;
    while ((corpse = wait(&status)) > 0)
        printf("Child %d exited with status 0x%.4X\n", corpse, status);

    printf("Received '%.*s' from child\n", nbytes, result);
}
...