[comp.lang.c] help on interprocess communication

bruey@cpsin2.cps.msu.edu (02/15/90)

Can any of you brainy netlanders give me a hint why this
doesn't work?  I've been cursing at this code for days
and I can't get it to work.  (I'm not even sure that the
forks are in the right order.  So basically, I'm lost.)  


#include<stdio.h>
main()  
{
/*  yes, I know I don't need all of these declarations, but
    this isn't the only part of the program  */ 
  int pid;
  int id1,id2,id3;
int rc=0,status,parent;
int filedes[2];
char *a,*buf1,*buf;

 
 pipe(filedes);
 if (fork())
   {
    printf("%d %d are filedes \n",filedes[0],filedes[1]);
    buf = "first message"; 
    write(filedes[1],buf,14);
    if(fork()) 
     { 
      read(filedes[1],buf1,14); 
       printf("in second   %s \n",buf1);    
     } 
   }

} 

flc@n.sp.cs.cmu.edu (Fred Christianson) (02/19/90)

In article <6456@cps3xx.UUCP> bruey@cpsin2.cps.msu.edu () writes:
>
>Can any of you brainy netlanders give me a hint why this
>doesn't work?
...
>    write(filedes[1],buf,14);
>    if(fork()) 
>     { 
>      read(filedes[1],buf1,14); 
		    ^
		    |
		0 ---
>       printf("in second   %s \n",buf1);    
>     } 
>   }
>
>} 

filedes[1] is for writing and filedes[0] is for reading.  I haven't used
pipes for a while, but that's what my man page says.

----
Fred 

cpcahil@virtech.uucp (Conor P. Cahill) (02/20/90)

In article <6456@cps3xx.UUCP> bruey@cpsin2.cps.msu.edu () writes:
> pipe(filedes);
> if (fork())
>   {
>    printf("%d %d are filedes \n",filedes[0],filedes[1]);
>    buf = "first message"; 
>    write(filedes[1],buf,14);
>    if(fork()) 
>     { 
>      read(filedes[1],buf1,14); 
>       printf("in second   %s \n",buf1);    
>     } 
>   }

Read PIPE(2) which should state something like:

filedes[0] is opened for reading and filedes[1] is opened for writing.

There are also several comments that could be made as to the error 
checking that is going on (or isn't going on), but I will just shut up
and give you  an example of the use of fork() and pipe() from the 
imake sources:

cppit(Imakefile, template, outfd)
	char	*Imakefile;
	char	*template;
	FILE	*outfd;
{
	FILE	*pipeFile;
	int	pid, pipefd[2];
#ifdef SYSV
	int	status;
#else	/* !SYSV */
	union wait	status;
#endif	/* !SYSV */
	char	*cleanedImakefile;

	/*
	 * Get a pipe.
	 */
	if (pipe(pipefd) < 0)
		LogFatal("Cannot make a pipe.", "");

	/*
	 * Fork and exec cpp
	 */
	pid = vfork();
	if (pid < 0)
		LogFatal("Cannot fork.", "");
	if (pid) {	/* parent */
		close(pipefd[0]);
		cleanedImakefile = CleanCppInput(Imakefile);
		if ((pipeFile = fdopen(pipefd[1], "w")) == NULL)
			LogFatalI("Cannot fdopen fd %d for output.", pipefd[1]);
		fprintf(pipeFile, "#define IMAKE_TEMPLATE\t\"%s\"\n",
			template);
		fprintf(pipeFile, "#define INCLUDE_IMAKEFILE\t\"%s\"\n",
			cleanedImakefile);
		fprintf(pipeFile, "#include IMAKE_TEMPLATE\n");
		fclose(pipeFile);
		while (wait(&status) > 0) {
			errno = 0;
#ifdef SYSV
			if ((status >> 8) & 0xff)
				LogFatalI("Signal %d.", (status >> 8) & 0xff);
			if (status & 0xff)
				LogFatalI("Exit code %d.", status & 0xff);
#else	/* !SYSV */
			if (status.w_termsig)
				LogFatalI("Signal %d.", status.w_termsig);
			if (status.w_retcode)
				LogFatalI("Exit code %d.", status.w_retcode);
#endif	/* !SYSV */
		}
		CleanCppOutput(outfd);
	} else {	/* child... dup and exec cpp */
		if (verbose)
			showargs(cpp_argv);
		dup2(pipefd[0], 0);
		dup2(fileno(outfd), 1);
		close(pipefd[1]);
		execv(cpp, cpp_argv);
		LogFatal("Cannot exec %s.", cpp);
	}
}

-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+

john@chinet.chi.il.us (John Mundt) (02/20/90)

In article <6456@cps3xx.UUCP> bruey@cpsin2.cps.msu.edu () writes:
>
>Can any of you brainy netlanders give me a hint why this
>doesn't work?  I've been cursing at this code for days
>and I can't get it to work.  (I'm not even sure that the
>forks are in the right order.  So basically, I'm lost.)  
>
>
>#include<stdio.h>
>main()  
>{
>  int pid;
>  int id1,id2,id3;
>int rc=0,status,parent;
>int filedes[2];
>char *a,*buf1,*buf;
>
> 
> pipe(filedes);
> if (fork())
>   {
>    printf("%d %d are filedes \n",filedes[0],filedes[1]);
>    buf = "first message"; 
>    write(filedes[1],buf,14);
>    if(fork()) 
>     { 
>      read(filedes[1],buf1,14); 
>       printf("in second   %s \n",buf1);    
>     } 
>   }
>
>} 

When you fork, you have two processes, the child and the parent.
The child process gets a return of 0 from fork if all goes well,
the parent the process ID of the child.  The normal way to do
the above is to put it in a switch statement like this:

	switch(fork()) {
	case -1	:	horrible_error_routine; exit(1);	/* error */
	case 0	:	do_child_thing();	/* like write to pipe */
			exit(0);		/* and die right away */
	default	:	do_parent_thing();	/* like read the pipe */
	}

Yours failed above since you never had a child process do anything.
You never left the parent process.  And, you only need one fork.
Hope this helps.
-- 
---------------------
John Mundt   Teachers' Aide, Inc.  P.O. Box 1666  Highland Park, IL
john@admctr.chi.il.us *OR* fred@teacha.chi.il.us
(312) 998-5007 (Day voice) || -432-8860 (Answer Mach) && -432-5386 Modem