The program as it is generates:

>Parent1
>Parent2
>In Child
>Parent3
Successfull...

If I remove the comment from line 31 - just below "//THE PROBLEM:" so the "gets(buff);" is executed it gives:

>Parent1
>Parent2

and... waits (both parent and child processes running - both waiting).
I would like to be able to read from pipe in child so I know what parent has sent.
How to do this so it does not "wait forever"?? Please help...

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

int toChild[2], fromChild[2];
pid_t pid;

if(pipe(toChild) != 0){
	perror("pipe() toChild");
	exit(1);
}
if(pipe(fromChild) != 0){
	perror("pipe() fromChild");
	exit(1);
}  
	if((pid = fork()) == -1)
	{
		perror("fork");
		return 1;
	}

	if(pid == 0)
	{/* CHILD */
		close(toChild[1]); //child won't write to child... :)
		close(fromChild[0]); //child won't read it's own messages
        
                dup2(toChild[0], STDIN_FILENO);
		dup2(fromChild[1], STDOUT_FILENO);

                char buff[5];
           //THE PROBLEM:             
                //gets(buff);
        
                puts(">In Child");

		return 0;
	}
	else
	{/* PARENT */
	
		close(toChild[0]); //paren't won't read his own messages...
		close(fromChild[1]); //paren't won't write to parent... :)
        
                //create streams:
                FILE *toChildStream;
                FILE *fromChildStream;
                if ((toChildStream = fdopen(toChild[1], "w")) == NULL)
                    return 1; //error: could not create stream
                if ((fromChildStream = fdopen(fromChild[0], "r")) == NULL)
                    return 1; //error: could not create stream
        
        puts(">Parent1");

    	        fputs(">Some text", toChildStream); //parent writes to child
        
        puts(">Parent2");
                         
                char buff[10];
    		while ( fgets(buff, 10, fromChildStream) != NULL) //read from child
                      puts(buff);
        
        puts(">Parent3");
	}

printf("\n\nSuccessfull...");
return 0;
}

Recommended Answers

All 6 Replies

> I would like to be able to read from pipe in child so I know what parent has sent.
> How to do this ...
the simplest way would be to use read and write on the anonymous pipe.
man read(2) http://www.freebsd.org/cgi/man.cgi?query=read&apropos=0&sektion=2&manpath=FreeBSD+7.0-stable&format=html
man write(2) http://www.freebsd.org/cgi/man.cgi?query=write&apropos=0&sektion=2&manpath=FreeBSD+7.0-stable&format=html

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

int main()
{
  int toChild[2] = {0}, fromChild[2] = {0};
  pid_t pid = -1 ;
  char parent_msg[] = "*** message from parent" ;
  char child_msg[] = "### message from child" ;

  pipe(toChild) ;
  pipe(fromChild) ;
  pid = fork() ;

  if(pid == 0)
  {/* CHILD */
    close(toChild[1]); //child won't write to child... :)
    close(fromChild[0]); //child won't read it's own messages
    char buff[ sizeof(parent_msg) ];
    read( toChild[0], buff, sizeof(parent_msg) ) ;
    pid_t pid = getpid() ;
    printf( "in child (pid %d): read: %s\n", pid, buff ) ;
    write( fromChild[1], child_msg, sizeof(child_msg) ) ;
    close(toChild[0]);
    close(fromChild[1]);
  }
  else
  {/* PARENT */
    close(toChild[0]); //paren't won't read his own messages...
    close(fromChild[1]); //paren't won't write to parent... :)
    write( toChild[1], parent_msg, sizeof(parent_msg) ) ;
    char buff[ sizeof(child_msg) ];
    read( fromChild[0], buff, sizeof(child_msg) ) ;
    pid_t pid = getpid() ;
    printf( "in parent (pid %d): read: %s\n", pid, buff ) ;
    close(toChild[1]);
    close(fromChild[0]);
  }
  return 0;
}

What is a pipe which is mentioned above. I dont know much so i get this doubt

Oh thanks for the wiki.

Thanks vijayan121 !!!

I still don't know why my original code doesn't work, though...

> I still don't know why my original code doesn't work, though...
to make the read end of a pipe the stdin for a process, you need to do a bit more than what was in your original code. the easy way to do this is to use popen and pclose which is a wrapper around the sequence of operations required.
http://www.freebsd.org/cgi/man.cgi?query=popen&apropos=0&sektion=3&manpath=FreeBSD+7.0-stable&format=html
for example, to pipe output through the the unix pager:

#include <stdio.h>

int main()
{
  /* popen does the following:
  a. create a pipe
  b. fork a child
  c. in parent: close the read end of the pipe
  d. in child: close the write end of the pipe
  e. in child: dup the read end of the pipe to stdin
  f. in child: exec the command. when the command 
      executes, its stdin is the read end of the pipe.
  g. returns a FILE* opened for writing to the parent.
      must be closed with pclose() 
      writes to the write end of the pipe */
  FILE* pipe_out = popen( "${PAGER:-/usr/bin/more}", "w" ) ;
  int i = 0 ;
  while( i<1024 ) fprintf( pipe_out, "line %d\n", ++i ) ;
  pclose( pipe_out ) ; /* calls waitpid(child) */
  return 0 ;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.