Pipes and fork() - How to write an array of int throught a pipe in C?

11,073

Solution 1

Pipes send bytes from one place to another. So you need to precisely specify what bytes you are going to send. Then make sure your sending code sends precisely those bytes and your receiving code expects precisely those bytes.

If you want it to work without having to do things the right way, do this:

Sender:

write(f[1], &val, sizeof(int));

Receiver:

for (int i = 0; i < 3; ++i)
  read(f[0], &buf[i], sizeof(int));

Note also printf("%d", *buff); prints the first element in the array (element zero).

Do not change the receiving code to read(f[0], buf, 3 * sizeof(int));. Your write is not atomic (because you call write three times) so you can't expect your read to be.

Solution 2

The bit pattern of -1845296639 is 0x92030201, assuming 32-bit two's complement ints.

So you get one byte of garbage from using the uninitialised buffer, and the three bytes written by the forked children.

Presumably, your platform is little-endian, and that would mean that in memory, the bytes are

0x01 0x02 0x03 0x92

so the written bytes arrived in order, as desired, although expecting read(...,...,3) to read three bytes after three children have written one byte each to the pipe is daring.

Share:
11,073
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    I'm triying to learn pipes in C and I'm stuck. I tried many things but I can't get the correct output.

    Next program should show: 123

    But Its output is always direction (unless I think):

    -1845296639

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    int main (int argc, char *argv[]){
    
        int i;
        int buff[4];
        int f[2];
    
        if(pipe(f) == -1)
            perror("pipe");
    
        for(i=0; i<3; i++){ 
    
            int val = i+1;
            switch(fork()){
                case -1:
                    perror("fork");
                    break;
                case 0:
                    close(f[0]);
                    write(f[1], &val, 1);
                    exit(0);
                    break;
                default:
                    break;
            }
        }
        close(f[1]);
    
        for(i=0; i<3; i++)
            wait(NULL);
    
        read(f[0], buff, i);
        printf("%d", *buff);
    
        exit(0);
    }