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);
}
}
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.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
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
That's the waitpid argument types
Could you describe what is happening, and what you expected to happen instead ?
The output you get would be a good start :)