简体   繁体   中英

I get a SIGPIPE error when using the write() C function

I really don't know why when I try to use write() on the file descriptor fd2 it just ends the program. When I use valgrind I get "Process terminating with default action of signal 13 (SIGPIPE)". The problematic line is write(fd2[1], &num, sizeof(num));

The point of this code is to make a child process,then have the child generate a random number and after that pass it to the parent process trough a pipe. Then the parent needs to create another child and pass the number he received from it's first child to the second child trough another pipe. This program is for one of my university courses.

/*
 * Ejemplo de codigo que genera un numero aleatorio y lo muestra por pantalla
 */
#include <sys/types.h>
#include <sys/wait.h>

 #include <time.h>
 #include <stdlib.h>
 #include <stdio.h>
#include <unistd.h>



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

    int pid1,pid2,fd1[2],fd2[2],pipe_status1,pipe_status2;

    pipe_status1=pipe(fd1);
    if(pipe_status1 == -1) {
        perror("Error creando la tuberia 1\n");
        exit(EXIT_FAILURE);
    }
    pipe_status2=pipe(fd2);
    if(pipe_status2 == -1) {
        perror("Error creando la tuberia 2\n");
        exit(EXIT_FAILURE);
    }

    pid1 = fork();
    if (pid1 <  0  )
    {
        printf("Error al emplear fork\n");
        exit (EXIT_FAILURE);
    }
    else  if(pid1 ==  0)
    {
            /* Inicializa el generador con una semilla cualquiera, OJO! este metodo solo
        se llama una vez */
        srand(time(NULL));
        /* Devuelve un numero aleatorio en 0 y MAX_RAND(un número alto que varia
        segun el sistema) */
        int r = rand();
        printf("El numero aleatorio es %d\n", r);

        close(fd1[0]);
        write(fd1[1], &r, sizeof(r));

        exit(EXIT_SUCCESS);
    }

    wait(NULL);
    int num;
    close(fd1[1]);
    read(fd1[0], &num, sizeof(num));
    printf("He recibido el numero: %d\n", num);


    close(fd2[0]);

    write(fd2[1], &num, sizeof(num));




    pid2 = fork();
        if (pid2 <  0  )
    {
        printf("Error al emplear fork\n");
        exit (EXIT_FAILURE);
    }
    else  if(pid2 ==  0)
    {
        close(fd2[1]);
        read(fd2[0], &num, sizeof(num));
        printf("He recibido el numero: %d\n", num);
    }

    wait(NULL);

    exit(EXIT_SUCCESS);

}

You get a SIGPIPE when you try to write to a pipe whose reading end has been closed. Since you do close(fd2[0]); on the line before this, that's why you get the error.

You need to create the second child before you do close(fd2[0]); in the parent. The child will inherit the pipe and that keeps it open.

The second child also needs to exit after it finishes doing its work, so it doesn't execute the parent code after it.

Change the second part of your code to:

    pid2 = fork();
    if (pid2 <  0  )
    {
        printf("Error al emplear fork\n");
        exit (EXIT_FAILURE);
    }
    else  if(pid2 ==  0)
    {
        close(fd2[1]);
        read(fd2[0], &num, sizeof(num));
        printf("He recibido el numero: %d\n", num);
        exit(EXIT_SUCCESS);
    }
    close(fd2[0]);
    write(fd2[1], &num, sizeof(num));

    wait(NULL);

    exit(EXIT_SUCCESS);

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM