Pipe error

hi guys, o have a big error
in this program but i cant solve

someone ?!

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

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

 int cont = 2, posicao; 
 char geraArquivo[100]= "|cat>>", espaco[3]=" ";
 char nomeArquivo[50], comando[1000], leitor[1000];

 if(argc>1)
 {
  strcpy(comando, argv[1]);
  while(cont< argc)
  {
   strcat(comando, espaco);
   strcat(comando, argv[cont]);
   cont++;
  }//fim do while

 printf("\nDigite o nome do arquivo: ");
 scanf("%s",nomeArquivo);
 printf("\n");
 strcat(geraArquivo,nomeArquivo);
 strcat(comando,geraArquivo);
 system(comando);
 }//fim do if

 else{
  printf("\nErro!\nDados para gera��o do arquivo n�o foram encontrados!\nPor favor entre com um comando do Sistema!\n");
  return 0;
 }//fim do else
 
 FILE *arq, *arq1, *arq2;
 arq = fopen(nomeArquivo,"r");
   arq1 = fopen("arquivoPai.txt","w+");
  arq2 = fopen("arquivoFilho.txt","w+");
 
   posicao = ftell(arq);


 int fp[2];
 int pf[2];
 int rc;
 int nbytes;
 char reader[1000];
 pipe(fp);
 pipe(pf);
 pid_t pid;
 pid = fork();

   while(!feof(arq))  //varrer arquivo
 {
  printf("OLHAE");
     if(pid == 0 && (posicao%2)==0)
  {
   close(fp[0]); // filho mandando pro pai fechar o "input"
   close(pf[1]);
   nbytes = read(pf[0], reader, sizeof(reader));
   fprintf(arq1,"%s \n",reader);
   fscanf(arq,"%s",leitor);
   write(fp[1],leitor, (strlen(leitor)+1));

  }
 
     else
  {
   close(fp[1]); // recebendo dados do filho fecharo "output"
   close(pf[0]);
   nbytes = read(fp[0],reader, sizeof(reader));
   fprintf(arq2,"%s \n",reader);
   fscanf(arq,"%s",leitor);
   write(pf[1],leitor,(strlen(leitor)+1));

  }

  posicao = ftell(arq);
 }
 
 exit(0);
 fclose(arq);
 fclose(arq1);
 fclose(arq2);
 

return 0;
}//fim da main

What, exactly, is this "big error"? what is happening or not happening?

3include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(){
 

     int pos;
     char leitor[1000];
     char reader[1000];

    FILE *arq, *arq1, *arq2;
     arq = fopen("teste.txt","r");
        arq1 = fopen("arquivoPai.txt","w+");
        arq2 = fopen("arquivoFilho.txt","w+");


     pipe(fp);
     pipe(pf);
     pid_t pid;
     pid = fork();

    pos = ftell(arq);
       while(!feof(arq))
     {
             if(pid == 0 && (pos%2)==0)
          {
               
               close(fp[0]);
               close(pf[1]);
               read(pf[0], reader, sizeof(reader));
               fprintf(arq1,"%s \n",reader);
               fscanf(arq,"%s",leitor);
               write(fp[1],leitor, (strlen(leitor)+1));
          }
  
             else
          {
  
               close(fp[1]);
               close(pf[0]);
               read(fp[0],reader, sizeof(reader));
               fprintf(arq2,"%s \n",reader);
               fscanf(arq,"%s",leitor);
               write(pf[1],leitor,(strlen(leitor)+1));

          }

      pos = ftell(arq);
     }
 
     exit(0);
     fclose(arq);
     fclose(arq1);
     fclose(arq2);
 

return 0;
}


i dont know how to create a two-way pipes

i need to send father-to-child a pair line of teste.txt
and send child-to-faher a odd line of teste.txt

and i need to print in two diferent .txt

but the program do nothing

Both are reading and nobody is writing. That is why they devise protocols. You need one, too.

i read this...

have another ways to do?!

2 pipes
father read... send to child... and child print in child.txt (a pair line)
after child read... send to father... and father print in father.txt ( a odd line)

The same problem can occur on sockets (tcp). That is why the http client speaks first, saying get or post or whatever. Otherwise, you need threads, processes (one to read and one to write), nonblocking IO (fcntl(), errno EAGAIN when would block) or poll/select (read when there is data, write when there is buffer space) to ensure reading supports writing. And then there are the high priority messages in the stream, EOF handling, error handling, and errno EINTR now and then as signals interrupt I/O subroutines. Oh, and on some systems, I have seen non blocking i/o still block on pipes when reading more than one byte.

There are atleast 3 errors, I could figure out. They are following:

1) You have not declered & defined pf,
2) You have not declered & defined fp,
3) You have not initilize pos; its using a garbage value.

The worst part is that you are controlling the program flow using and AND condition with (pid == 0) && (pos % 2 == 0). You are taking the mod of a garbage value, isn't it?

Now could you please try to analyse the result of that if() expression for the below two cases:
1) When pos has a garbage value which is an odd number,
2) When pos has a garbage value which is an even number

I think its pretty enough for you to know what went wrong.

Also, just declare & define pf and fp as below:

int pf[2], fp[2];

Rest is okey in your program.

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(){
 

     int pos = 0;
     char leitor[1000] = "Testando Leitor";
     char reader[1000] = "Testando Reader";
    int fp[2];
    int pf[2];
    int n;
    int m;
    char line[1000];

    FILE *arq, *arq1, *arq2;
     arq = fopen("teste.txt","r");
        arq1 = fopen("arquivoPai.txt","w");
        arq2 = fopen("arquivoFilho.txt","w");


     pipe(fp);
     pipe(pf);
     pid_t pid;
     pid = fork();

    if (pid == -1)
        printf("\n Erro de cria��o\n");

    else
    {
        pos = ftell(arq);
           while(!feof(arq))
         {
                 if((pos%2)==0)
              {
                if(pid != 0)
                {                           
                    close(fp[0]);
                    fscanf(arq,"%s",leitor);
                      write(fp[1],leitor, (strlen(leitor)+1));
                    printf("Father send to arquivoFilho.txt : %s \n",leitor);
                    close(fp[1]);
                    n = read(fp[0],leitor, sizeof(leitor));
                    fprintf(arq2,"%s \n",leitor);

                }                   
 

              }
  
                 if((pos%2)!=0)
              {
                  if(pid == 0)
                {
                    
                    close(pf[0]);
                    fscanf(arq,"%s",reader);
                     write(pf[1],reader,(strlen(reader)+1));
                    printf("Child send to arquivoPai.txt : %s \n",reader);
                    close(pf[1]);
                     m = read(pf[0], reader, sizeof(reader));
                     fprintf(arq1,"%s \n",reader);
                    
                    //exit(0);
                }
                

              }

              pos ++;
            
         }
    }
 
     exit(0);
     fclose(arq);
     fclose(arq1);
     fclose(arq2);
 

return 0;
}

in the first pipe... the father send to the child text corretly

but the second just send a simple line

Why are you using if((pos%2)==0)
???

to get odd and pair lines in the text

You know ftell() would return you the location of the file pointer inside the file pointed by arg and the return value would be just an unsigned number. This number could be odd or even depending on the file size, correct?

Now when you just control the flow with if((pos % 2) == 0) ; what would happen? It'll either execute the if-part or the else-part only. Meaning either you'd be executing either if (pid == 0) or if (pid != 0) in one session of your program run but never the both. Hence either only the child runs when the file size is an odd number ( i.e. if((pos % 2) == 0) ) and gets blocked for ever, despite correctly reading on the pipe's correct descriptor (i.e. fd[0] -without having the parent writing anything over fd[1]) :slight_smile: .

Or the parent runs (when the file size is even) without having anyone as its listener (as the child won't be able to execute).

Thats it.

ok... i understod

how i fix this ?!

teste.txt

father send to child the ("arquivoFilho.txt")

child send to father ("arquivoPai.txt")

can i change this program to do ?!

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(){
 

 	int pos = 0;
 	char leitor[1000] = "Testando Leitor";
 	char reader[1000] = "Testando Reader";
	int fp[2];
	int pf[2];
	int n;
	char line[1000];

	FILE *arq, *arq1, *arq2;
 	arq = fopen("teste.txt","r");
        arq1 = fopen("arquivoPai.txt","w");
        arq2 = fopen("arquivoFilho.txt","w");


 	pipe(fp);
 	pipe(pf);
 	pid_t pid;
 	pid = fork();

	if (pid == -1)
		printf("\n Erro de cria��o\n");

	else
	{
		pos = ftell(arq);
   		while(!feof(arq))
 		{
			//imprimindo certo de pai pra filho
     			if((pos%2)==0)
  			{
				if(pid != 0)
				{
					close(fp[0]);
					fscanf(arq,"%s",leitor);
  					write(fp[1],leitor, (strlen(leitor)+1));
					printf("Pai mando pro arquivoFilho.txt : %s \n",leitor);
					close(fp[1]);
					n = read(fp[0],leitor, sizeof(leitor));
					fprintf(arq2,"%s \n",leitor);

				}


  			}

			//imprimindo somente uma linha de filho pra pai
     			if((pos%2)!=0)
  			{
  				if(pid == 0)
				{
					close(pf[1]);
   					read(pf[0], reader, sizeof(reader));
   					fprintf(arq1,"%s \n",reader);
					printf("Filho manda pro arquivoPai.txt : %s \n",reader);
					exit(0);
				}
				else
				{
					close(pf[0]);
   					fscanf(arq,"%s",reader);
   					write(pf[1],reader,(strlen(reader)+1));
				}


  			}

  			pos ++;
 		}
	}

 	exit(0);
 	fclose(arq);
 	fclose(arq1);
 	fclose(arq2);

return 0;
}

cause when i run this program
i send all pair lines to the child but only the first line odd

like this

arquivoFilho.txt

arquivoPai.txt

only the first line

---------- Post updated at 12:16 PM ---------- Previous update was at 11:52 AM ----------

i didnt know how it worked but work like i need

i used 2 pipes, ok ?!
i send father to child and child to father ?!

and the code is:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(){
 

 	int pos = 0;
 	char leitor[1000] = "Testando Leitor";
 	char reader[1000] = "Testando Reader";
	int fp[2];
	int pf[2];
	int n;
	int m;

	FILE *arq, *arq1, *arq2;
 	arq = fopen("teste.txt","r");
        arq1 = fopen("arquivoPai.txt","w");
        arq2 = fopen("arquivoFilho.txt","w");


 	pipe(fp);
 	pipe(pf);
 	pid_t pid;
 	pid = fork();

	if (pid == -1)
		printf("\n Erro de cria��o\n");

	else
	{
		pos = ftell(arq);
   		while(!feof(arq))
 		{
     			if((pos%2)==0)
  			{
				if(pid != 0)
				{		   				
					close(fp[0]);
					fscanf(arq,"%s",leitor);
  					write(fp[1],leitor, (strlen(leitor)+1));
					printf("Pai mando pro arquivoFilho.txt : %s \n",leitor);
					close(fp[1]);
					n = read(fp[0],leitor, sizeof(leitor));
					fprintf(arq2,"%s \n",leitor);

				}   				
 

  			}
  
     			if((pos%2)!=0)
  			{
  				if(pid != 0)
				{
					
					close(pf[0]);
					fscanf(arq,"%s",reader);
   					write(pf[1],reader,(strlen(reader)+1));
					printf("Filho manda pro arquivoPai.txt : %s \n",reader);
					close(pf[1]);
   					m = read(pf[0], reader, sizeof(reader));
   					fprintf(arq1,"%s \n",reader);
					
					//exit(0);
				}
				

  			}

  			pos ++;
			
 		}
	}
 
 	exit(0);
 	fclose(arq);
 	fclose(arq1);
 	fclose(arq2);
 

return 0;
}

i think i used the same parent to send in both arqs