mercredi 22 juin 2016

Pipes between more than 2 children fail - C

How can I make functional pipes between 3 or more children?

I use this command:

./function n with n the number of children.

And the the father makes n pipes and n children.

After that the children close the pipes they will not use.

Then the father writes something in the first pipe, and the first children read it, and write it to the next pipe. The last child should write the content in the stdout.

When I use only 1 child it works perfect. When I try to use 2 children, the last one reads from the pipe: -1 characters and when I try to use 3 children, I got segment violation and the code doesn't work.

Hope you can help me, here is the code.

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

void use_pipes(int i);
void write_father(void);
//int* pp[2];
int (*pp)[2];
int childrens;

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

childrens = atoi(argv[1]);
pp = malloc(sizeof (*pp)*childrens);
int p,i,j,aux;

printf("I'm the parent and i'm making %d childrensn",childrens);
for (i = 0; i < childrens; i++) {
        if (pipe(pp[i]) < 0) {
                perror("Error in pipe()");
                exit(1);
    }

    }//for

    for (i = 0; i < childrens; i++) {
        printf("I'm the parent pid: %d and I'm going to make the child nº: %dn", getpid(),i);
        p=fork();

        switch (p) {
                case -1:
                    printf("We couldn't make the child nº:%dn",i);
                    exit(1);
                case 0:
                    //printf("I'm nº: %d, and I start my coden",i);

                    for(aux=0;aux<childrens;aux++){
                if (aux==i){
                    //printf("I'm the children nº: %d and I'm going to close the pipe[%d] of writingn", i,i);
                    close(pp[i][1]);
                }
                            else if(aux==i+1){
                    //printf("I'm the children nº: %d and I'm going to close the pipe[%d] of readingn", i,aux);
                                close(pp[aux][0]);
                            }
                            else {
                    //printf("I'm the children nº: %d and I'm going to close the pipe[%d]n", i,aux);
                                close(pp[aux][0]);
                                close(pp[aux][1]);
                            }
                    }//for

                    //printf("I finished to close my unused pipesn");
                    use_pipes(i);
            exit(0);

                default:
                    if (i==0){
                        close(pp[0][0]);
                    for (j = 1; j < childrens; j++) {
                    close(pp[j][0]);
                    close(pp[j][1]);
                    }
            }//for

    }//switch
    }//for of fork

write_father();
for(i=0;i<childrens;i++){
    wait(NULL);
}

}//main

void write_father(){
int wroten;
char buffer[50]= "Hello World";
int len = strlen(buffer);
wroten = write(pp[0][1],buffer,len);
printf("The parent wrote: %d charactersn",wroten);
}

void use_pipes (int n_children) {
int readed;
char buffer [50];
readed = read(pp[n_children][0],buffer,sizeof(buffer));
printf("Children %d readed from pipe[%d][0]: %d charactersn",n_children,n_children,readed);
if(n_children!=childrens-1){
    printf("Children %d write in the pipe[%d][1]: %d charactersn",n_children,n_children+1,readed);
    write(pp[n_children+1][1],buffer,readed);
}
else
    write(1,buffer,readed);


}

Aucun commentaire:

Enregistrer un commentaire