Pipes and fork

I dont know what am i doing wrong, the parent process sends the lines of a file to the children them  the children count them and send them to the parent.
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define BUFFERSIZE 100

typedef struct array{
    int lines;
    int pid;
    }ARRAY;

int fd0[2];

void handler();

int main(int argc,const char ** argv)
{
    FILE *fp, *fp0, *fp1, *fp2, *fp3;
    ARRAY *p;
    char str[BUFFERSIZE];
    pid_t p1,p2,p3;
    int fd1[2],fd2[2],fd3[2], count1=0, count2=0, count3=0, line=0;
    if((p = (ARRAY*)malloc(sizeof(ARRAY)))==NULL){
        printf("ERROR ALLOCATING MEMORY\n");
        exit(1);
    }

    if (pipe(fd0) == -1){
    {
        perror("pipe call error");
        exit(1);
    }
    if (pipe(fd1) == -1)
    {
        perror("pipe call error");
        exit(1);
    }
    if (pipe(fd2) == -1)
    {
        perror("pipe call error");
        exit(1);
    }
    if (pipe(fd3) == -1)
    {
        perror("pipe call error");
        exit(1);
    }

    if ((p1=fork())==-1)
    {
        perror("Child fail");
        exit(1);
    }
    }
    else
    {
        if (p1==0)
        {
            close(fd0[0]);
            fp0 = fdopen(fd0[1], "w");
            if(fp0==NULL){perror("file pointer (0) of child (p1):");}
            close(fd0[1]);
            close(fd1[1]);
            fp1 = fopen(fd1[0], "r");
            if(fp1== NULL){perror("file pointer (1) of child (p1):");}
            close(fd1[0]);
            while(fgets(str, BUFFERSIZE, fp1)!= NULL)
            {
                printf("%d : %s\n", getpid(), str);
                count1++;
            }
            p->pid=getpid();
            p->lines=count1;
            fwrite(p, sizeof(ARRAY), 1, fp0);
            fclose(fp0);
            fclose(fp1);
            if(kill(getpid(), SIGUSR1)==-1){ perror("Kill fail child p1:"); exit(1);}
            exit(EXIT_SUCCESS);
        }
        else if ((p2=fork())==-1)
        {
            perror("Child fail");
            exit(1);
        }
        else
        {
            if (p2==0)
            {
                close(fd0[0]);
                fp0 = fdopen(fd0[1], "w");
                if(fp0==NULL){perror("file pointer (0) of child (p2):");}
                close(fd0[1]);
                close(fd1[1]);
                fp2 = fopen(fd2[0], "r");
                if(fp2==NULL){perror("file pointer (2) of child (p2):");}
                close(fd2[0]);
                while(fgets(str, BUFFERSIZE, fp2)!= NULL)
                {
                    printf("%d : %s\n", getpid(), str);
                    count2++;
                }
                p->pid=getpid();
                p->lines=count2;
                fwrite(p, sizeof(ARRAY), 1, fp0);
                fclose(fp0);
                fclose(fp2);
                if(kill(getpid(), SIGUSR1)==-1){ perror("Kill fail child p2:"); exit(1);}
                exit(EXIT_SUCCESS);
                }
            else if ((p3=fork())==-1)
            {
                perror("Child fail");
                exit(1);
            }
            else
            {
                if (p3==0)
                {
                    close(fd0[0]);
                    fp0 = fdopen(fd0[1], "w");
                    if(fp0==NULL){perror("file pointer (0) of child (p3):");}
                    close(fd0[1]);
                    close(fd3[1]);
                    fp3 = fopen(fd3[0], "r");
                    if(fp3==NULL){perror("file pointer (3) of child (p3):");}
                    close(fd3[0]);
                    while(fgets(str, BUFFERSIZE, fp3)!= NULL)
                    {
                        printf("%d : %s\n", getpid(), str);
                        count3++;
                    }
                    p->pid=getpid();
                    p->lines=count3;
                    fwrite(p, sizeof(ARRAY), 1, fp0);
                    fclose(fp0);
                    fclose(fp3);
                    if(kill(getpid(), SIGUSR1)==-1){ perror("Kill fail child p3:"); exit(1);}
                    exit(EXIT_SUCCESS);

                }else{ //parent code
                    if(signal(SIGUSR1,handler)==SIG_ERR)
                    {
                        perror("signal:");
                        exit(1);
                    }
                    if(fp==NULL){perror("fp:"); exit(1);}

                    if(fp1==NULL){perror("fp1:"); exit(1);}
                    close(fd1[0]);
                    fp1=fopen(fd1[1], "w");
                    close(fd1[1]);

                    if(fp2==NULL){perror("fp2:"); exit(1);}
                    close(fd2[0]);
                    fp2=fopen(fd2[1], "w");
                    close(fd2[1]);

                    if(fp3==NULL){perror("fp3:"); exit(1);}
                    close(fd3[0]);
                    fp1=fopen(fd3[1], "w");
                    close(fd3[1]);

                    while(fgets(str, BUFFERSIZE, fp)!=NULL)
                    {
                        if(line == 0)
                        {
                            fputs(str, fp1);
                            line++;
                        }else if(line == 1)
                                {
                                    fputs(str, fp2);
                                    line++;
                                }
                                else if(line == 2)
                                        {
                                            fputs(str, fp3);
                                            line=0;
                                        }
                    }
                    fclose(fp1);
                    fclose(fp2);
                    fclose(fp3);
                    waitpid(p1, NULL, 0);
                    waitpid(p3, NULL, 0);
                    waitpid(p3, NULL, 0);
                    close(fd0[0]);
                    }

                }
            }
        }
    }


void handler()
{
    FILE *fp0;
    ARRAY *p;
    fp0 = fdopen(fd0[0], "r");
    if(fp0== NULL){
        exit(1);
    }else{
        if((p = (ARRAY*)malloc(sizeof(ARRAY)))==NULL){
            printf("ERROR ALLOCATING MEMORY\n");
            exit(1);
            }
        fread(p, sizeof(ARRAY), 1, fp0);
        printf("PID %d == num linhas = %d \n", p->pid, p->lines);
    }
}

Open in new window

VasconcelosAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Infinity08Commented:
>> I dont know what am i doing wrongI dont know what am i doing wrong

Could you describe what is happening, and what you expected to happen instead ?

The output you get would be a good start :)
0
VasconcelosAuthor Commented:
i expect it to given a certain file location he prints the lines and the pids of the text, right now it just prints "no file location and bad address" :)
0
Infinity08Commented:
>> right now it just prints "no file location and bad address" :)

I don't find that message in the code you posted.

Could you please clearly describe what's happening ? It would help if you copy-pasted the output (when you run the code) here.
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

jkrCommented:
Your compiler should actually be screaming blue murder:

65:             fp1 = fopen(fd1[0], "r");

65: warning: passing argument 1 of 'fopen' makes pointer from integer without a cast

IOW: You are passing the wrong arguments, an integer where a 'char*' is requited. Such a file does not exist ("no file location...") and also is very unlikely to represent any valid memory region ("... and bad address"). That's what I get (on BSD):

fp:: No such file or directory
file pointer (3) of child (p3):: No such file or directory
file pointer (2) of child (p2):: Bad address

(the error messages are created by 'perror()')
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Duncan RoeSoftware DeveloperCommented:
In new code, you will generally find it beneficial to have a zero tolerance to compiler warnings. A compiler warning often indicates code which has no chance of running successfully, even though it may compile. That is the reason for having them.
Fix all warnings below. The fopen warnings are because you should be using fdopen. Line 15 should be "void handler(void);". Insert the lines "#include <sys/types.h>" and "#include <sys/wait.h>". This will enable the compile to check the argument types - it can't do that just now which is the reason for the warning. Insert "return 0;" at the end of main() to remove the warning at line 193 - not essential but you want NO warnings.
See if you can figure the reason for the uninitialized warnings - I have to go now. Will look in this evening.

07:53:06$ gcc -Wall -Wstrict-prototypes -Wmissing-prototypes -g3 -ggdb ee59.c -o ee59
ee59.c:15: warning: function declaration isn't a prototype
ee59.c: In function 'main':
ee59.c:65: warning: passing argument 1 of 'fopen' makes pointer from integer without a cast
/usr/include/stdio.h:249: note: expected 'const char * __restrict__' but argument is of type 'int'
ee59.c:95: warning: passing argument 1 of 'fopen' makes pointer from integer without a cast
/usr/include/stdio.h:249: note: expected 'const char * __restrict__' but argument is of type 'int'
ee59.c:125: warning: passing argument 1 of 'fopen' makes pointer from integer without a cast
/usr/include/stdio.h:249: note: expected 'const char * __restrict__' but argument is of type 'int'
ee59.c:151: warning: passing argument 1 of 'fopen' makes pointer from integer without a cast
/usr/include/stdio.h:249: note: expected 'const char * __restrict__' but argument is of type 'int'
ee59.c:156: warning: passing argument 1 of 'fopen' makes pointer from integer without a cast
/usr/include/stdio.h:249: note: expected 'const char * __restrict__' but argument is of type 'int'
ee59.c:161: warning: passing argument 1 of 'fopen' makes pointer from integer without a cast
/usr/include/stdio.h:249: note: expected 'const char * __restrict__' but argument is of type 'int'
ee59.c:184: warning: implicit declaration of function 'waitpid'
ee59.c: At top level:
ee59.c:197: warning: function declaration isn't a prototype
ee59.c: In function 'main':
ee59.c:193: warning: control reaches end of non-void function
ee59.c:58: warning: 'p1' may be used uninitialized in this function
ee59.c:147: warning: 'fp' may be used uninitialized in this function
ee59.c:149: warning: 'fp1' may be used uninitialized in this function
ee59.c:154: warning: 'fp2' may be used uninitialized in this function
ee59.c:159: warning: 'fp3' may be used uninitialized in this function

Open in new window

0
Duncan RoeSoftware DeveloperCommented:
That's the waitpid argument types
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.