Link to home
Start Free TrialLog in
Avatar of Vasconcelos
Vasconcelos

asked on

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

Avatar of Infinity08
Infinity08
Flag of Belgium image

>> 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 :)
Avatar of Vasconcelos
Vasconcelos

ASKER

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" :)
>> 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.
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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

That's the waitpid argument types