用管道与孩子进行fork()通信

时间:2019-05-12 12:25:22

标签: c process fork dup2

我在与父亲和孩子沟通一个半星期的过程中遇到了问题。我设法帮助它在父亲和孩子之间工作,但当涉及到两个和三个孩子时,我失败了。

我希望在每个execv中将char'1'或'0'返回给父亲的char数组。

我试图绘制管道方向和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);
}

0 个答案:

没有答案